MySQL номерной знак снижает производительность поиска? - PullRequest
0 голосов
/ 24 января 2012

У меня небольшая проблема, и я очень признателен за помощь.

У меня есть таблица MyISAM, содержащая 33 000 000 строк со следующей структурой данных:

id -> Primary Key, Unsigned INT, Auto-Increment
characters -> Unique Indexed, varchar(15)
price -> decimal (10,2)
active -> tinyint(1)

Я написалСценарий, который принимает значение поиска от пользователя, а затем создает следующий запрос, основанный на вводе пользователем слова «Кевин»:

SELECT characters, price 
FROM listings_dvla 
WHERE active=TRUE 
AND LOWER(REPLACE(characters, ' ', '')) REGEXP '^[a-z0-9]*[(k)]+[a-z0-9]?[(e)(3)]+[a-z0-9]?[(v)]+[a-z0-9]?[(i)(1)]+[a-z0-9]?[(n)(11)(1v)]+[a-z0-9]*' 
ORDER BY characters ASC 
LIMIT 0, 12

Просто чтобы объяснить, регулярное выражение просто пытается сопоставить каждую букву по порядкуили последовательность букв, которые означают то же самое на «языке номерного знака», например.N == 1V

Дело в том, что этот запрос черт возьми!20+ секунд.Я много читал и обнаружил, что использование символов в качестве первичного ключа медленнее, поэтому я вынул его и добавил поле идентификатора.Я использовал EXPLAIN, который показывает индексы, и они имеют значение NULL, я предполагаю, что это потому, что REGEXP отключает их (я тоже это где-то читал).

У меня вопрос, есть ли у кого-нибудь какие-нибудь яркие идеи, чтобы серьезно увеличить эти запросыспектакль?Поскольку я чувствую, что не знаю чего-то очень важного, чтобы это было быстрее.

Я изменю структуру таблицы, если это будет необходимо, поэтому не беспокойтесь о том, чтобы дать мне довольно экстремальный ответ.

Спасибо за чтение, буду признателен за любые предложения.

Ответы [ 3 ]

0 голосов
/ 24 января 2012

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

Во-вторых, очевидная альтернатива состоит в том, чтобы запустить код, который модифицирует «kevin» в его различных формах номерного знака на клиенте, и преобразовать его в запрос «in»:

select *
from listings_dvla 
where active = 1
and cleaned_characters in ('kev1n', 'kev1iv'.....)

Если вы также хотите иметь возможность искать слова в символах - то есть возвращать A10 KEV для параметра KEV, вы можете немного обмануть, создав дополнительные столбцы с подстроками.

таблица листингов_двла

ID    characters   cleaned_characters   characters_right7  characters_right6 characters_right5 characters_right4 characters_right3
1     A10 KEV       a10kev               10kev               0kev             kev     
2     KT 11 TCP     kt11tcp              t11tcp               11tcp           1tcp     tcp    

Грязно, но, создав индекс по всем столбцам, вы сможете получать очень быстрые запросы. Вставить / обновить будет медленнее, хотя ...

0 голосов
/ 24 января 2012

, поскольку вы не используете поле ID в предложении where, mysql не использует ваш первичный ключ.Там нет никаких сюрпризов.

Полагаю, вам нужен индекс FULL TEXT для столбца персонажа.

0 голосов
/ 24 января 2012

Строковые запросы в MySQL очень медленные. Я даже не уверен, применимы ли к ним какие-либо ключи (кроме FULLTEXT).

Вы используете функции для условия where, что означает, что каждые записи должны быть загружены, обновлены с заменой и ниже и сравниваться с регулярным выражением (mysql не может заранее знать, каков будет результат быть).

По сути: с таким регулярным выражением у вас никогда не будет быстрого запроса.

Однако вы можете добавить поле, например isWord TINYINT DEFAULT 0 (с индексом на нем) и использовать запрос:

UPDATE listings_dvla SET isWord = 1 WHERE active=TRUE 
AND LOWER(REPLACE(characters, ' ', '')) REGEXP '^[a-z0-9]*[(k)]+[a-z0-9]?[(e)(3)]+[a-z0-9]?[(v)]+[a-z0-9]?[(i)(1)]+[a-z0-9]?[(n)(11)(1v)]+[a-z0-9]*' 

И чем выбирать записи по * проиндексированному полю с: SELECT ... WHERE ... AND isWord = 1

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