Задавайте вопросы, мы ответим
Вы не зашли.
Страниц: 1
Тема закрыта
Доброго времени суток!
Ситуация следующая: есть select, который очень долго отрабатывается (много данных в таблице и пробежаться нужно по всем ним), результат этого select'a требуется в нескольких местах. Хотелось бы его закешировать (чтобы из другой sql-сессии сделать такой запрос и получить закешированный результат), но не кешируется .
Выполняю запрос из MySQL QueryBrowser'a
SELECT SQL_CACHE * from SQLINFO.t1 order by tstart desc limit 1;
после этого подключаюсь клиентом mysql, выполняю идентичный запрос - запрос опять выполняется несколько минут.
Между выполнениями select'ов таблица не меняется.
Пробовал наоборот - сперва путем mysql, после через MySQL Query Browser - результат оказался предсказуем, то же самое.
Переменные окружения mysql:
mysql> show variables like '%cach%';
+------------------------------+----------------------+
| Variable_name | Value |
+------------------------------+----------------------+
| binlog_cache_size | 32768 |
| have_query_cache | YES |
| key_cache_age_threshold | 300 |
| key_cache_block_size | 1024 |
| key_cache_division_limit | 100 |
| max_binlog_cache_size | 18446744073709547520 |
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 33554432 |
| query_cache_type | ON |
| query_cache_wlock_invalidate | OFF |
| table_cache | 512 |
| thread_cache_size | 8 |
+------------------------------+----------------------+
13 rows in set (0.00 sec)
Понимаю, что проще было бы создать временную табличку или положить результат в файл, так и сделаю, если не получится договориться с кешированием, но все ж хотелось бы ). Подскажите кто знает, в чем может быть загвоздка.
Неактивен
Повторяемо ли, если перенести таблицу на локальную машину? Не надо Query Browser. Проверяйте просто двумя клиентами. Может быть Query Browser меняет одну букву запроса (например делает FROM заглавными буквами) и для кэша это уже другой запрос.
Неактивен
Если перенести таблицу на локальную машину - повторяемо.
От query browser'a отказался, пробовал гонять запросы тремя способами:
1) непосредственно через mysql-клиент (но подключался с разных хостов).
2) программа на c (использует mysql c api)
3) php-шный скрипт.
Получался везде один и тот же результат (перед каждым экспериментов делал reset query cache):
запускаю программу на одном хосте первый раз - запрос отрабатывается медленно.
запускаю ее же (просто скопировал бинарник на другой хост) сразу же после на другом хосте - запрос отработался быстро.
то же самое с php-скриптом - запускал его с разных хостов - первый раз ( сразу после reset query cache ) отрабатывается долго. второй раз (что с этой, что с другой машины) - сразу.
то же самое через mysql-клиент.
То есть если пробовать на "одном и том же" "материале" - нормально идет.
А вот если сперва сделать в mysql-клиенте, а потом в php, а потом через программу (пробовал разные вариации) - то каждый выполняется долго. И Qcache_queries_in_cache увеличивается на единицу после каждого запроса, хотя они одинаковы.
Запрос везде написан одними и теми же символами, без лишних пробелов и прочее.
Кодировка в системах всех utf-8.
Я уж и помыслить себе не могу, чем эти запросы отличаться могут между собой...
Может быть есть способ посмотреть, какой именно запрос пришел в кеш? Или еще как-то диагностировать?
Отредактированно deadka (11.05.2010 15:59:58)
Неактивен
А пользователь один и тот же?
Включите журнал запросов (--log) и посмотрите, одинаковые ли запросы приезжают
(должны совпадать с точностью до символа — проверка идет по md5 запроса).
Неактивен
Спасибо, включил --log, помогло в диагностике.
У меня не кешировалось из-за несовпадения set names.
Ряд экспериментов показал, что результат будет взят из кеша если:
1) запросы идентичны досимвольно (включая регистр, конечно).
2) подключение идет к одной и той же базе (даже если в запросе указана совсем другая!)
3) set names одинаков
Касательно пользователей - видимо это не учитыватся - прогонял под разными пользователями, и стучался на хосты и через доменное имя и через ip-адрес (в журнале по-разному отображались, конечно) на самого себя и через localhost и через 127.0.0.1 - везде успешно вынималось.
Так что проблема решена, спасибо!
Только уточнить хочу насчет задания параметра --log. Я логирование включил через my.cnf - а как прямо в командную строку добавить? Или так и надо - через my.cnf? Или лучше mysqld в /etc/rc.d/init.d менять?
Неактивен
Я обычно делаю через my.cnf
Кстати, в 5.1 есть возможность регулировать это на живом сервере (т.е. если у
Вас в my.cnf прописан --general-log-file, то можно включать-выключать его
через SET GLOBAL general_log = 1).
Неактивен
Ну да, судя по всему лучше через my.cnf, но в принципе так ведь тоже можно? - в смысле залезть в shell-скрипт mysqld и в нем "ручками" добавить опцию --log? Или так все ж не рекомендуется делать?
Касательно 5.1 - спасибо, буду иметь в виду, пока еще на 5.0.77 живу ).
Неактивен
Ну, все зависит от того, как у Вас принято. Обычная технология подразумевает
редактирование конфигов, т.к. именно там другие администраторы будут искать
настройки.
Неактивен
paulus написал:
Обычная технология подразумевает
редактирование конфигов, т.к. именно там другие администраторы будут искать
настройки.
Да, похоже на то.
rgbeast написал:
Не надо Query Browser. Проверяйте просто двумя клиентами. Может быть Query Browser меняет одну букву запроса
(например делает FROM заглавными буквами) и для кэша это уже другой запрос.
Если интересно: эксперимент показал, что Query Browser тоже честно берет из кеша (если set names предварительно указать тот же, что был в той сессии, в которой результат запроса попал в кеш). Пробовал с различными регистрами, по умолчанию он ничего не меняет.
Григорий, Павел, подскажите пожалуйста, а все же сам этот хеш (запрос => результат) посмотреть как-то можно?
Или придется ограничиваться переменными, которые описывают его состояние?
И опять же - есть ли возможность получить данные про то, откуда результат - из кеша или "по-настоящему получен"?
Отредактированно deadka (13.05.2010 13:02:01)
Неактивен
Насколько я знаю, посмотреть нельзя. Смысла в том, чтобы узнать, получен ли
ответ из кэша или вычислен, — тоже не много. Но второе можно узнать, например,
профилированием запроса.
Неактивен
Вопрос, похоже, исчерпан, спасибо!
Неактивен
Тема закрыта
Страниц: 1