2011-05-05 13 views
9

Poniżej kwerendy używam do przeszukiwania osobę emailMysql Poprawa skuteczności wyszukiwanego z symboli wieloznacznych (%%)

SELECT * 
    FROM phppos_customers 
    JOIN phppos_people ON phppos_customers.person_id = phppos_people.person_id 
    WHERE deleted = 0 
    AND email LIKE '%f%' 
ORDER BY email ASC 

Czy dodanie indeksu na „email” przyspieszyć zapytania?

+0

[To wyjaśnienie] (http://use-the-index-luke.com/sql/where-clause/searching-for-ranges/like-performance-tuning) może pomóc zrozumieć, dlaczego to nie działa. –

+1

[** Ta odpowiedź **] (http://stackoverflow.com/a/22531268/793309) pokazuje ładną technikę - indeksowanie wszystkich sufiksów - dzięki czemu tego typu zapytanie może działać bardzo dobrze, ale kosztem niektórych dodatkowe kodowanie i większe wymagania dotyczące pamięci. – antinome

Odpowiedz

14

Nie, ponieważ MySQL nie będzie w stanie wykorzystać indeks gdy masz wiodącą wieloznaczny. Jeśli zmienisz swój LIKE na "f%", wtedy będzie mógł użyć indeksu.

8

Nie, Mysql nie użyje indeksu ponieważ LIKE argument (%f%) zaczyna się od symbolu wieloznacznego %. Jeśli zaczyna się od stałej, zostanie użyty indeks.

Więcej informacji: 7.5.3. How MySQL Uses Indexes

1

Nie będziesz w stanie zrobić tego szybciej dzięki LIKE, tak jak wszyscy mówią (o % na początku), ale możesz trochę poprawić, dołączając po uprzednim przefiltrowaniu swoich ludzi.

SELECT * 
    FROM (SELECT * 
      FROM `phppos_customers` 
     WHERE `deleted` = 0 
      AND `email` LIKE '%f%') `t_customers` 
    JOIN `phppos_people` ON `t_customers`.`person_id`=`phppos_people`.`person_id` 
ORDER BY `email` asc 
+0

Używanie 'LIKE' z lewej zamiennika bocznym w widoku tabeli pochodzącej/inline nadal nie użyje indeksu ... –

+0

nigdy nie powiedział, że ... –

+0

PO pyta konkretnie o użyciu indeksu ... I” Jestem skłonny zgodzić się na to, ponieważ zdajesz sobie sprawę, że nie dostarczasz niczego wartościowego na to pytanie ... –

4

symboli wieloznacznych lewą część operacji LIKE zapewnia, że ​​wskaźnik, jeśli istnieje na kolumnie email, nie mogą być użyte.

Wyszukiwanie pełnotekstowe (FTS) jest preferowaną składnią do wyszukiwania ciągów w tekście za pomocą SQL. MySQL has native FTS functionality, using the MATCH/AGAINST syntax (Requires the table to use the MyISAM engine for v.5.5 and below. InnoDB FTS supported on v.5.6+):

SELECT c.*, p.* 
    FROM PHPPOS_CUSTOMERS c 
    JOIN PHPPOS_PEOPLE p ON p.person_id = c..person_id 
    WHERE deleted = 0 
    AND MATCH(email) AGAINST('f') 
ORDER BY email 

Istnieją jednak inne technologie FTS, takie jak Sphinx.

+0

I szczegółowo pełnotekstowego i rozmawialiśmy trochę o Sphynx tutaj: http://stackoverflow.com/questions/3338889/how-to-find-similar-results-and-sort-by-similarity/3339034#3339034 –

+0

Jak MySQL 5.6 Funkcjonalność FTS jest teraz dostępna w tabelach InnoDB. – blo0p3r

3

W moim poście tu opisać w szczegółach, to technika, która pozwala na użyć indeksu z LIKE do szybkiego %infix% poszukiwaniu, kosztem pewnego dodatkowego miejsca:

https://stackoverflow.com/a/22531268/543814

Tak długo, jak struny są stosunkowo małe, wymagania dotyczące pamięci są ogólnie do przyjęcia.

Według Google średni adres e-mail to 25 znaków. Spowoduje to zwiększenie wymaganej pamięci średnio o współczynnik 12.5 i zapewnia szybkie indeksowanie w zamian. (Zobacz mój post do obliczeń.)

Z mojego punktu widzenia, jeśli przechowujesz 10 000 adresów e-mail, powinieneś dobrze przechowywać (odpowiednik) około 100 000 adresów e-mail. Jeśli to wystarczy, aby umożliwić korzystanie z indeksu, wydaje się, że jest to akceptowalny kompromis. Często miejsce na dysku jest tanie, a wyszukiwania nieindeksowane są niedostępne.

Jeśli zdecydujesz się na takie podejście, sugeruję ograniczenie długości wprowadzania adresów e-mail do 64 znaków. Te rzadkie (lub atakujące) adresy e-mail o takiej długości będą wymagać dorazy więcej niż zwykle. To daje:

  1. Ochrona przed intruzem próbującym zalać Twoją bazę danych, ponieważ nadal nie są to imponujące ilości danych.
  2. Oczekiwanie, że większość adresów e-mailowych nie ma takiej długości.

Jeśli wziąć pod uwagę 64 znaków zbyt surowy wymóg, należy 255 zamiast na najgorszym wzrost magazynowania czynnika 127.5. Śmieszny? Możliwie. Prawdopodobne? Nie. Szybko? Bardzo.

Powiązane problemy