Разница между производительностью двух запросов SQL? - PullRequest
3 голосов
/ 15 августа 2010

В моей таблице есть поле с текстовым типом данных.

Есть ли разница в производительности для следующих двух запросов sql:

 select * from tablename where fieldname="xyz%";
 select * from tablename where fieldname="%zyx";

Если бы нам нужно было выполнить выполнениеиз этих запросов я думаю, что нам нужно будет сделать:

Нам нужно сопоставить два регулярных выражения (xyz * и * zyx).

Нам нужно будет проверить строковые символыодин, начиная с начала.

Для первого запроса нам нужно будет прочитать первые три символа, чтобы увидеть, есть ли совпадение, но для второго нам нужно будет прочитать, пока мы не получим конецстрока, чтобы определить, произошло ли совпадение.Но если у нас где-то хранится длина строки, мы можем непосредственно прочитать последние три символа, что дает производительность, аналогичную первой.

Мой вопрос заключается в том, показывают ли коммерческие базы данных, такие как mysql и oracle, какую-либо разницу в производительности ввыполнение запросов.

Ответы [ 4 ]

6 голосов
/ 15 августа 2010

Существует определенная разница между производительностью на всех БД.Первый случай будет определенно быстрее, если столбец будет проиндексирован.

У меня был похожий экземпляр в моем проекте, где пользователю также было разрешено искать «заканчивается» (как ваш второй запрос).

Поскольку это часто использовавшаяся операция и запрос выполнялся медленно,

  1. Мы добавили в таблицу дополнительный столбец, в котором хранилось обратное имя поля.
  2. проиндексировал этот столбец
  3. всякий раз, когда заканчивался поиск, мы искали в этом новом столбце :) (путем изменения исходной строки поиска)

, поэтому ваш второй запрос становится:

 select * from tablename where fieldname_rev="xyz%";

Этот подходсделал это так быстро, как начинается с запроса.

4 голосов
/ 15 августа 2010

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

Во-первых, помните, что мы не ищем лучший алгоритм для сопоставлениястрока.Мы ищем лучший алгоритм, чтобы найти все подходящие строки в наборе из N строк.Мы хотим работать лучше, чем «Делать алгоритм X, N раз».

Если имя поля НЕ проиндексировано, то разница в производительности между этими двумя запросами будет очень небольшой - движок SQL просто собирается выполнитьсовпадать с первыми 3 или последними 3 байтами строки, что является просто вопросом смещения в правильную ячейку памяти.

Если имя поля IS проиндексировано, между двумя поисками будет огромная разница в производительностипотому что вместо проверки всех N строк мы можем отбросить большую часть данных.

т.е. для версии "xyz%" мы можем использовать бинарный поиск.

Начнем с серединыэлемент, который, как оказалось, «Питер».Мы можем немедленно отбросить все до 'peter' и получить средний элемент для остатка - 'samantha' и так далее, пока не найдем записи, начинающиеся с 'xyz'.

С версией "% xyz" мы не можем этого сделать, поскольку ЛЮБАЯ строка может потенциально совпадать в конце, нам нужно просмотреть каждую строку.

По мере увеличения размера нашей таблицы разница между этими двумя подходами становится большой.

Решение по созданию поля / индекса для обратного имени поля позволяет нам снова использовать технику двоичного поиска.(В некоторых базах данных это возможно сделать без создания дополнительного поля, но с использованием определенных типов индексов, виртуальных столбцов и т. Д.).

Это значительно упрощается - для получения подробной информации о фактической реализации базы данныхиндексы, посмотрите на B-Tree и B * Tree индексы.

2 голосов
/ 15 августа 2010

Если индексировано fieldname, большинство коммерческих баз данных могут преобразовать первый запрос в интервальный поиск

select * from tablename where fieldname>="xyz" and fieldname<"xy{"

что очень быстро.

1 голос
/ 16 августа 2010

Да, есть разница между следующими двумя запросами:

select * from tablename where fieldname LIKE "xyz%";
select * from tablename where fieldname LIKE "%zyx";
  1. Оператор равно ("=") не допускает подстановочные знаки в SQL - вам нужно использовать LIKE
  2. Запросы совершенно разные
    • "xyz%" вернет записи, которые начинаются с "xyz"
    • "%xyz "вернет записи, которые оканчиваются на" xyz "
  3. Предполагая, что для столбца fieldname существует индекс"% xyz "может не использовать индекс - но «xyz%» может, что означает, что это будет быстрее.

Самый быстрый способ найти подстроки в текстеиспользовать полнотекстовый поиск (FTS) - и Oracle, и MySQL имеют свои собственные встроенные функции, и существуют сторонние инструменты, такие как Sphinx и Solr.

...