Autor Zpráva
Sylar
Profil
Zdravím,
máte zde někdo zkušenosti s fulltextovým vyhledáváním nad tabulkami s řádově statisíci záznamy, blížíčím se k milonovým položkám?
Testoval jsem vyhledávání nad pouhými desetitisíci, při pěti prohledávaných sloupcích - vše bylo v pohodě - velmi vysoká rychlost hledání. Nyní počet záznamů stoupl na pouhý dvojnásobek a rychlost je strašná, trvá to několik sekund (cca 10 sec.).

Zkoušel jsem to v boolean modu
SELECT DISTINCT p.nazev AS nazev, p.id AS id, p.description AS description, url, p.img AS img, delivery, cena, s.nazev AS shop, s.link AS shop_link,
   (SELECT count(id) FROM ?_shops_produkty WHERE nazev LIKE p.nazev) AS pocet_shopu
      FROM ?_shops_produkty p, ?_shops s
      WHERE p.zobraz = '1' AND
         (MATCH(p.description) AGAINST('taška' IN BOOLEAN MODE) OR 
         MATCH(p.nazev) AGAINST('taška' IN BOOLEAN MODE) ) AND 
         p.shop = s.id
      ORDER BY s.payed DESC,
          (1 * MATCH(p.description) AGAINST('taška*')) + 
          (2 * MATCH(p.nazev) AGAINST('taška*')) DESC, clicked DESC
       LIMIT 0, 10
ale i přirozeném jazyce
SELECT DISTINCT p.nazev AS nazev, p.id AS id, p.description AS description, url, p.img AS img, delivery, cena, s.nazev AS shop, s.link AS shop_link,
   (SELECT count(id) FROM ?_shops_produkty WHERE nazev LIKE p.nazev) AS pocet_shopu
      FROM ?_shops_produkty p, ?_shops s
      WHERE p.zobraz = '1' AND
         (MATCH(p.description) AGAINST('taška') OR
         MATCH(p.nazev) AGAINST('taška') ) AND p.shop = s.id
      ORDER BY s.payed DESC,
         (1 * MATCH(p.description) AGAINST('taška*')) +
         (2 * MATCH(p.nazev) AGAINST('taška*')) DESC, clicked DESC
      LIMIT 0, 10

a u obou variant je rychlost vyhledávání cca stejná. Nevím ale co by mohlo výrazně zpomalovat nebo naopak zrychlovat vyhledávání.
DISTINCT? vnořený SELECT, který počítá počet shopů nebo počet fulltextových indexů? Je lepší mít více indexů nad více slopuci nebo jeden index s více sloupci? V druhém případě, ale není možné pak řadit výsledky dle relevance (v boolean modu) nebo ano?
Kajman
Profil
Jak se s těmi dalšími řádky změnily explainy?
Sylar
Profil
Kajman:
co to?
Kajman
Profil
Plány provádění oněch dotazů
explain select ...
Sylar
Profil
Kajman:
explain partitions mi vyhodilo toto

    [res] => Array
        (
            [0] => Array
                (
                    [id] => 1
                    [select_type] => PRIMARY
                    [table] => p
                    [partitions] => 
                    [type] => ALL
                    [possible_keys] => 
                    [key] => 
                    [key_len] => 
                    [ref] => 
                    [rows] => 21900
                    [Extra] => Using where; Using temporary; Using filesort
                )

            [1] => Array
                (
                    [id] => 1
                    [select_type] => PRIMARY
                    [table] => s
                    [partitions] => 
                    [type] => eq_ref
                    [possible_keys] => PRIMARY
                    [key] => PRIMARY
                    [key_len] => 3
                    [ref] => seznamshopu_cz_www.p.shop
                    [rows] => 1
                    [Extra] => 
                )

            [2] => Array
                (
                    [id] => 2
                    [select_type] => DEPENDENT SUBQUERY
                    [table] => b_shops_produkty
                    [partitions] => 
                    [type] => ALL
                    [possible_keys] => 
                    [key] => 
                    [key_len] => 
                    [ref] => 
                    [rows] => 21900
                    [Extra] => Using where
                )

        )

a explain extended toto

    [res] => Array
        (
            [0] => Array
                (
                    [id] => 1
                    [select_type] => PRIMARY
                    [table] => p
                    [type] => ALL
                    [possible_keys] => 
                    [key] => 
                    [key_len] => 
                    [ref] => 
                    [rows] => 21900
                    [filtered] => 100.00
                    [Extra] => Using where; Using temporary; Using filesort
                )

            [1] => Array
                (
                    [id] => 1
                    [select_type] => PRIMARY
                    [table] => s
                    [type] => eq_ref
                    [possible_keys] => PRIMARY
                    [key] => PRIMARY
                    [key_len] => 3
                    [ref] => seznamshopu_cz_www.p.shop
                    [rows] => 1
                    [filtered] => 100.00
                    [Extra] => 
                )

            [2] => Array
                (
                    [id] => 2
                    [select_type] => DEPENDENT SUBQUERY
                    [table] => b_shops_produkty
                    [type] => ALL
                    [possible_keys] => 
                    [key] => 
                    [key_len] => 
                    [ref] => 
                    [rows] => 21900
                    [filtered] => 100.00
                    [Extra] => Using where
                )

        )

ale moc moudrý z toho nejsem. Obojí je prováděno při těch cca 22.000 záznamech.

===

A ještě se chci zeptat na stránkování. Kvůli němu musím provádět ten hlavní dotaz dvakrát, nejprve abych zjistil, kolik je položek celkem a další dotaz na vybrání pouze té skupiny položek, co chci uživateli zobrazit. To asi také poměrně dost brzdí rychlost. Je nějaká možnost jak to provést jedním dotazem nebo je lepší pak ty položky, které chci zobrazit filtrovat už pomocí PHP?
Kajman
Profil
A v explainu v rychlém dotaze a v pomalém dotaze je nějaký rozdíl?

A jak je rychlé samotné vyhledávání ve fulltextovém indexu?
SELECT p.id,
       MATCH(p.description) AGAINST('taška') fld,
       MATCH(p.nazev) AGAINST('taška') fln
FROM   shops_produkty p
WHERE  MATCH(p.description) AGAINST('taška') OR MATCH(p.nazev)
        AGAINST('taška')

Pro poddotaz počítající pocet_shopu bude dobrý index na sloupci nazev.

Sylar:
A ještě se chci zeptat na stránkování.

Můžete použít select SQL_CALC_FOUND_ROWS, kdy to počet řádků podle limitu, ale funkce na zjištění počtu řádků vrátí celkový počet vyhovujících řádků.
Sylar
Profil
Kajman:
děkuji, SQL_CALC_FOUND_ROWS je skvělá věc.

ohledně indexu pro počet shopů, ten tam již je ... v jiném formuláři se totiž vyhledává i mezi obchody, takže i v této tabulce je index na sloupci název.

snížil jsem počet indexů na 2 - název a popis obchodu (což zřejmě také velmi ovlivŇuje vyhledávání, že?) a nyní rychlost se opět vrátila na původní (avšal při dvakrát menším počtu položek), tak uvidíme, až opět počet stoupne.

rád bych si o fulltextu nastudoval něco více, ale všude nacházím pouze články se základy fulltextu v mysql. Nevíš o nějakém pěkném článku s pokročilejšími informacemi?

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: