Назад | Перейти на главную страницу

Несоответствующее истекшее время для запроса mysql / mariadb

Проверяя прошедшее время для запроса к базе данных для мониторинга munin, я создал скрипт, часть измерения времени:

start=$(sed 's/^0*//'<<< `date +%N`)
/usr/bin/mysql -u 3da_d9 -p****** --host="127.0.0.1" --port=4002 -e "SELECT f.*, AVG(l.value) AS vote_value, COUNT(l.value) AS vote_count, 0 AS active_feature, c.name from 3dallusions_joomla_d9.jom3_downloads_files AS f INNER JOIN 3dallusions_joomla_d9.jom3_downloads_containers AS c ON f.containerid = c.id LEFT JOIN 3dallusions_joomla_d9.jom3_downloads_log AS l ON l.type = 3 AND l.fileid = f.id AND l.value != 0" > /dev/null
end=$(sed 's/^0*//'<<< `date +%N`)
if [ "$end" -lt "$start" ]; then
    end=$(($end+1000000000))
fi
elapsed=$(($end - $start))
elapsed=$(($elapsed/1000000))
echo $elapsed

Я проверил логику измерения времени, заменив вызов SQL простым сном. Это всегда дает стабильный результат.

База данных и клиент - это MariaDB 10.1 из репозитория Debian Stretch.

Меня озадачивает то, что при первом запуске скрипта ответ составляет около 10 миллисекунд. Последующие прогоны дают около 50 миллисекунд. После того, как скрипт некоторое время не запускался, снова получается результат около 10.

Почему в первый раз запрос будет в пять раз быстрее, чем при повторении? Можно было ожидать, что кеширование вызовет противоположный эффект. Что происходит?

Посмотрите, сколько накладных расходов вы выполняете - date, sed, mysql, mysql login и т. Д.

Вместо этого сделайте проверку даты как можно ближе к действию:

SELECT @start := SYSDATE(6), log(10), @end := SYSDATE(6);
SELECT UNIX_TIMESTAMP(@end) - UNIX_TIMESTAMP(@start) AS 'seconds';

+----------+
| seconds  |
+----------+
| 0.000037 |
+----------+

Это говорит о 37 микросекундах, но все еще есть куча накладных расходов.

Также рассмотрите BENCHMARK функция:

mysql> SELECT BENCHMARK(1000000, log(10));
+-----------------------------+
| BENCHMARK(1000000, log(10)) |
+-----------------------------+
|                           0 |
+-----------------------------+
1 row in set (0.03 sec)

Это говорит о 0,03 микросекунды; Я этому верю. BENCHMARK это способ определения времени функций или выражений.

Если вы можете использовать PHP, просто выполните

$start = microtime(true);
... perform the query ...
$end = microtime(true);
echo $end - $start, ' seconds';

Это будет «достаточно хорошо» для полных заявлений.