Как определить производительность запроса на основе индекса (а, б) - PullRequest
0 голосов
/ 27 февраля 2020

Как ранжировать эти запросы с точки зрения производительности?

Проблема заключается в заданном индексе (a, b) и 4 запросах.

  1. Выбрать * из пользователь, где a = 0 И b = 0.

  2. Выбрать * от пользователя, где a = 0 ИЛИ b = 0.

  3. Выбрать * из пользователь, где a> 0 И b = 0.

  4. Выберите * у пользователя, где a = 0 И b> 0.

Какой запрос выполняется самый быстрый и наименее эффективный.

Как его определить.

Ответы [ 2 ]

3 голосов
/ 27 февраля 2020

Чтобы определить, какой запрос будет теоретически быстрее / медленнее, вы можете посмотреть, как работает индекс базы данных: это, по сути, построение дерева сначала из значений из столбца, а затем со значениями из столбца b

Некоторые примечания:

Поиск точного значения быстрее и поиск диапазона (например,> 0) только потому, что вам нужно сканировать меньше данных.

Это означает, что запрос будет выполняться быстрее для условий, где обе переменные по сравнению с const:

  1. Выберите * у пользователя, где a = 0 И b = 0

Второй тип запроса: первый столбец в индексе имеет сравнение с константой, а второй - диапазон, так как вы снова уменьшаете количество сканирований (вам не нужно сканировать Bs для A! = 0):

Выберите * от пользователя, где a = 0 И b> 0

Следующий запрос частично сканирует диапазон A (поэтому он медленнее 1/2), но может довольно быстро соответствовать b:

Выберите * от пользователя, где a> 0 И b = 0

Последний - это то, где у вас есть ИЛИ, в основном вы делаете 2 отдельных сканирования, а затем объединяете результаты (или просто выполняете полное сканирование):

Выберите * от пользователя, где a = 0 ИЛИ b = 0
1 голос
/ 10 марта 2020

Как говорит Илья, плюс ...

where a > 0 AND b = 0

будет использовать только частично INDEX(a,b); b часть индекса будет неиспользована. INDEX(b,a) было бы хорошо для этого where.

Один из способов улучшить производительность OR - это разделить его на две SELECTs и UNION их вместе:

(SELECT * FROM t WHERE a=0)
UNION ALL  -- or DISTINCT if you need de-dupping
(SELECT * FROM t WHERE b=0)

Подробнее: http://mysql.rjweb.org/doc.php/index_cookbook_mysql

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...