Autor Zpráva
Honzaaa
Profil *
Ahoj, mám celkem objemnou databázi (2mil záznamů), ale potřebuju z ní filtrovat podle více parametrů. A ještě více hodnot.

Filtruji ze 4 sloupců, nad kterými mám společný index. A pro ty sloupce ještě musím použít where IN (). Čim více hodnot zadám do where in, tak tím je čas delší (aý 15s)

Zajímalo by mě, zda se to dá udělat nějak jinak. Někde jsem četl o dočasné tabulce, ale nějak o tom nemohu nic najít (nevím ani co přesně hledat)

Předem moc díky
Alphard
Profil
Dočasná tabulka na filtrování? To nevím, ale zdá se mi to kontraproduktivní.
Jak máte ty indexy? Máte i samostatný na sloupci, podle kterého vybíráte where in? Co říká explain?
Honzaaa
Profil *
   id => "1"
   select_type => "SIMPLE" (6)
   table => "table" (11)
   type => "range" (5)
   possible_keys => "collumn1,collumn2,collumn3,collumn4" (100)
   key => "kayName" (32)
   key_len => "776" (3)
   ref => NULL
   rows => "470141" (6)
   Extra => "Using where; Using index" (24)

collumn jsou názvy těch sloupců, nechci zveřejňovat přímo o co jde, jelikož jsem vázán dohodou o mlčenlivosti. Díky za pohopení

jinak indexy jsou i samostatné
Alphard
Profil
A jak vypadá ten dotaz? Klidně si přejmenujte sloupce, ale nemyslím, že jeden dotaz je porušením smlouvy.
Mně se zdá divných těch 15 s, to je na 2 M záznamů strašně moc. Když to where in vynecháte, tak je to ok? A kolik záznamů vám to vrátí bez in, musí se to pak filtrovat ještě hodně (myslím na poddotaz).
Honzaaa
Profil *
nic složitého
SELECT count(*) FROM table WHERE param in ( params ) AND param2 in ( params2 ) AND param3 in ( params3 ) AND param4 in ( params4 )

kde params je až 15 čísel

Nevím také, jaký na to má vliv můj pc, dělám to na localhostu, takže předpokládám, že na serveru by to mělo být lepší, jelikož můj ntb už je staršího data.
Kajman
Profil
Je některý z těch indexů "collumn1,collumn2,collumn3,collumn4" vícesloupcový?

U více sloupcových navíc částečně záleží na pořadí použitých sloupců. U sloupců je důležitá i četnost hledaných hodnot, aby index bylo výhodné vůbec používat.
Tori
Profil
Zkoušela jsem teď něco podobného na menším vzorku: pokud je ve všech množinách IN stejný počet hodnot, použije se složený index. Pokud ne, použije se index na sloupci, který porovnáváte s nejmenší množinou (kvůli AND je to nejvíc limitující podmínka) - to je zřejmě těch 470k řádků - (a zbytek už nevím, v jakém pořadí se prohledává).
edit: aha tak to není úplně jak jsem myslela, při jiném pokusu se i při stejně velkých množinách hodnot použil jen jeden z jednosloupcových indexů.

Ale - pokud byste měl dočasnou tabulku se čtyřmi sloupci, podle kterých filtrujete, s primárním indexem přes všechny 4 sloupce, pak do ní nasypal všechny možné kombinace hodnot z těch čtyř množin parametrů (pro 15 možností to bude okolo 50k řádků), můžete použít join: select t1.* from table inner join tmp using (param, param2, param3, param4) DB pak může prohledat jen index, takže by to mohlo být o dost rychlejší.
edit: ale nevím, jak dlouho by trvalo vytvoření dočasné tabulky + nasypání dat, jestli se to vyplatí.
Honzaaa
Profil *
[#6] Kajman
v tom explainu je použit vícesloupcoví index keyName nad sloupci column1-column4
Pořadí u dotazu jsem také zkoušel měnit.

[#7] Tori
Teď jsem to zkusil a vytvoření tabulky s naplněním trvá 90ms a dotaz na počet také 90ms.
Ale bohužel vrací to špatný počet. Když nad tím přemýšlím, tak nevím, jestli to tak půjde.
Ono když si do té tmp tabulky dám např data:

col1 | col2 | col3 | col4
10 100 1000 3000
20 200 2000 3000

tak on ten join už asi neudělá všechny možnosti tzn:
10 200 1000 3000
20 100 1000 3000
atd...
Tori
Profil
Honzaaa:
on ten join už asi neudělá všechny možnosti
V dočasné tabulce by musely být všechny možné kombinace těch možností (takže pro max. 15 možností pro každý sloupec to bude max. 50625 řádků). Kartézský součin libovolného počtu polí se dá vytvořit např. takhle: http://stackoverflow.com/questions/4549794/how-to-find-every-possible-combination-of-arrays-in-php (ale možná by bylo efektivnější použít prostě 4 vnořené cykly for a rovnou skládat SQL).
Honzaaa
Profil *
[#9] Tori
No nějak to ještě zkusím promyslet, možná pomůže omezení na rozsah na 10 hodnot, to už jde znatelně rychle a v praxi je snad nemožné, aby nastal případ, že bude všude zadáno vše na maximum.

Každopádně mockrát díky za rady

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:

0