У меня проблемы с производительностью по некоторым запросам к базе данных, которые имеют большие возможные наборы результатов.
Запрос в вопросе, у меня есть три AND
с в предложении WHERE
Имеет ли значение порядок пунктов?
Например, если я сначала поставлю предложение ASI_EVENT_TIME (поскольку это приведет к удалению большинства результатов из любого из предложений.
Это улучшит время выполнения запроса?
QUERY:
SELECT DISTINCT activity_seismo_info.*
FROM `activity_seismo_info`
WHERE
activity_seismo_info.ASI_ACTIVITY_ID IS NOT NULL AND
activity_seismo_info.ASI_SEISMO_ID IN (43,44,...,259) AND
(
activity_seismo_info.ASI_EVENT_TIME>='2011-03-10 00:00:00' AND
activity_seismo_info.ASI_EVENT_TIME<='2011-03-17 23:59:59'
)
ORDER BY activity_seismo_info.ASI_EVENT_TIME DESC
ОБЪЯСНЕНИЕ запроса:
+----+-------------+---------+-------+---------------------------+--------------+---------+------+-------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------------------+--------------+---------+------+-------+-----------------------------+
| 1 | SIMPLE | act...o | range | act...o_FI_1,act...o_FI_2 | act...o_FI_1 | 5 | NULL | 65412 | Using where; Using filesort |
+----+-------------+---------+-------+---------------------------+--------------+---------+------+-------+-----------------------------+
С помощью:
PHP 5.2
MySQL 5.0.51a-3ubuntu5.4
Propel 1.3
Symfony 1.2.5
mysql
performance
mysql-5
Патрик
источник
источник
order by
принадлежит в базе данных.Ответы:
Не думаю. Оптимизатор запросов должен быть достаточно умным.
Вы можете попробовать переставить предложения WHERE и увидеть, что EXPLAINS говорит вам то же самое в каждом случае.
О том, что можно сделать для оптимизации этого запроса: есть ли индекс для ASI_EVENT_TIME? (для этого запроса я считаю наиболее важным, поскольку вы также сортируете результаты по нему).
Есть ли индексы в двух других полях (ASI_SEISMO_ID и ASI_ACTIVITY_ID)?
Было бы полезно, если бы вы опубликовали структуру таблицы.
источник
Из документации :
Так что да, он должен быть таким же, как порядок столбцов в составном индексе .
источник
WHERE c = 'foo' AND a = 'bar' AND b = 'foobar'
и индекс по-прежнему подходит для использования.Нет, это не важно.
Оптимизатор выполняет кучу простых преобразований сразу после анализа SQL - это одно из них.
источник
оптимизирует так же, как
Тем не мение,
Не удается оптимизировать обе части. Например,
не может эффективно использовать INDEX (a, b) или INDEX (b, a)
Чтобы выразить это по-другому, сначала используются любые '=' тесты AND'd вместе в предложении WHERE, затем один может быть обработан не - '=' (IN, BETWEEN,> и т. Д.). Не более одного можно эффективно оптимизировать.
Ваш запрос имеет 3 таких пункта.
Как оказалось, INDEX (EVENT_TIME), вероятно, наиболее полезен - он поможет с одним из AND, и его можно использовать, чтобы избежать «файловой сортировки» для ORDER BY.
Если нет повторяющихся строк (почему, черт возьми, будет?), Тогда избавьтесь от DISTINCT. Это вызывает еще больше усилий.
Пожалуйста, предоставьте SHOW CREATE TABLE и SHOW TABLE STATUS, задавая вопросы о производительности.
Обновление ... Более новые версии (например, MySQL 5.7) могут в некоторых ситуациях работать
IN( list of constants )
почти так же, как=
. Чтобы не рисковать, придерживайтесь этого порядка (каждая часть необязательна):=
.INs
.источник
MySQL, где документация по оптимизации гласит:
Таким образом, для оптимизатора запросов целесообразно опустить порядок HOW, в котором мы использовали столбцы в запросе (не только MySQL, но и SQL - декларативный язык, и он должен делать то, что мы хотим, а не то, что мы хотим).
Однако я все еще люблю иметь такой же вид для столбцов составного ключа в запросе, но иногда это неизбежно, например, когда мы используем ORM или ActiveRecord, в некоторых средах, таких как yii2, настройка критериев отношения будет добавлена в конце в состоянии «включено», но нам все еще нужны возможности QueryBuilders в разных частях приложения.
источник
Любое поле, которое используется в ваших предложениях WHERE / HAVING и имеет высокую селективность (количество уникальных значений / общее количество записей> 10% ~ 20%), ДОЛЖНО быть проиндексировано.
Итак, если в вашем
ASI_EVENT_TIME
столбце много возможных значений, сначала внесите их в указатель. Затем, как сказал @ypercube, попробуйте переставить их и посмотрите, что EXPLAIN говорит вам. Должно быть все вокруг одинаково.Кроме того, вы хотите, чтобы вы посмотрели на индексирование SQL как фильтры . Хотя это не то, на что вам нужен ответ, но вы все равно узнаете, как работает индексация.
* Изменить: обратитесь к ссылкам, приведенным ниже в комментариях, чтобы узнать больше об индексации.
источник