Mam duży stół z 5 milionami słów. Muszę znaleźć słowa zaczynające się od dynamicznego ciągu znaków. Ale kiedy używam operatora LIKE ze zmienną łańcuchową, zapytanie staje się zbyt długie.

Na przykład to zapytanie zajmuje 1,3 sekundy:

set @pattern = 'f%';
select * from words where Word like @pattern limit 100;

Następne zapytanie zajmuje 0,0 sekundy:

select * from words where Word like 'f%' limit 100;

Ale oba zapytania wykonują tę samą pracę.

Jaki może być powód, dla którego żądania mają bardzo różny czas trwania? Jak wyeliminować tę różnicę?

0
Palindromer 31 marzec 2020, 20:11

3 odpowiedzi

Najlepsza odpowiedź

Okazało się, że zmienne mają zestaw znaków utf8mb4 (domyślny zestaw znaków mojej bazy danych), ale kolumna Word ma zestaw znaków utf8.

Więc wszystko, co muszę zrobić, to przekonwertować zestaw znaków za pomocą utf8:

set @pattern = CONVERT('f%' USING utf8);
select * from words where Word like @pattern limit 100;
1
Palindromer 31 marzec 2020, 17:46
  • Skonstruuj zapytanie, zamiast używać @variables. Ewentualnie użyj procedury składowanej jako sposobu korzystania z funkcji Przygotuj i Wykonaj.
  • Przełącz się z MyISAM na InnoDB.
  • Czy obchodzi Cię, które 100 rzędów? LIMIT bez ORDER BY zwykle nie jest właściwe.
  • Jeśli są to naprawdę „słowa” (a nie tylko litery takie jak „f”), rozważ FULLTEXT.
  • SHOW VARIABLES LIKE 'char%'; - może to oznaczać prostsze miejsce na dostosowanie CHARACTER SET.
0
Rick James 1 kwiecień 2020, 14:53

Jest istotnym problemem, ponieważ przechowujemy wartość w stercie, a następnie używamy jej w zapytaniu, a nie bezpośrednio w zapytaniu, proponuję ulepszyć dokumentację do czytania wydajności mysql poniżej: https://geekflare.com/mysql-performance-tuning/

0
Beqir kuci 31 marzec 2020, 17:47