Lassú Query

gazsesz képe

Sziasztok!

Egy jó ideje küzdünk a szolgáltatóval egy olyan problémán, hogy beragadnak SQL-ek, de eddig nem jöttünk rá, hogy mi az oka. Hátha tud valaki segíteni!

"Érdekességek:"
- bekapcsoltam a devel modul logját is, de abban nem találtam ilyen sql-t, pedig a szolgáltató
szerint a logolás ideje alatt is volt ilyen beragadás.
- két szótár van, az sql az egyes szótárra (td.vid=1) hivatkozik, viszont nem ebben vannak tn.nid 166, 124-es kategóriák, hanem a 2-es szótárban, így az SQL mindig 0 eredményt hoz.

A honlap "méretei":
- köbö 1700 node
- 2 szótár, összesen köbö 250 kategória (kifejezés)
- napi látogatók száma 100-300

Hol lehet a hiba?

Alább a horror sql.

SELECT td.vid, td.tid, td.name, COUNT(DISTINCT(n.nid)) AS count FROM term_data td INNER JOIN term_node tn ON tn.tid = td.tid INNER JOIN term_node tn0 ON tn.nid = tn0.nid INNER JOIN term_node tn1 ON tn.nid = tn1.nid INNER JOIN term_node tn2 ON tn.nid = tn2.nid INNER JOIN term_node tn3 ON tn.nid = tn3.nid INNER JOIN term_node tn4 ON tn.nid = tn4.nid INNER JOIN term_node tn5 ON tn.nid = tn5.nid INNER JOIN term_node tn6 ON tn.nid = tn6.nid INNER JOIN term_node tn7 ON tn.nid = tn7.nid INNER JOIN term_node tn8 ON tn.nid = tn8.nid INNER JOIN term_node tn9 ON tn.nid = tn9.nid INNER JOIN term_node tn10 ON tn.nid = tn10.nid INNER JOIN term_node tn11 ON tn.nid = tn11.nid INNER JOIN term_node tn12 ON tn.nid = tn12.nid INNER JOIN term_node tn13 ON tn.nid = tn13.nid INNER JOIN term_node tn14 ON tn.nid = tn14.nid INNER JOIN term_node tn15 ON tn.nid = tn15.nid INNER JOIN term_node tn16 ON tn.nid = tn16.nid INNER JOIN term_node tn17 ON tn.nid = tn17.nid INNER JOIN term_node tn18 ON tn.nid = tn18.nid INNER JOIN term_node tn19 ON tn.nid = tn19.nid INNER JOIN term_node tn20 ON tn.nid = tn20.nid INNER JOIN term_node tn21 ON tn.nid = tn21.nid INNER JOIN term_node tn22 ON tn.nid = tn22.nid INNER JOIN term_node tn23 ON tn.nid = tn23.nid INNER JOIN term_node tn24 ON tn.nid = tn24.nid INNER JOIN term_node tn25 ON tn.nid = tn25.nid INNER JOIN term_node tn26 ON tn.nid = tn26.nid INNER JOIN term_node tn27 ON tn.nid = tn27.nid INNER JOIN term_node tn28 ON tn.nid = tn28.nid INNER JOIN term_node tn29 ON tn.nid = tn29.nid INNER JOIN term_node tn30 ON tn.nid = tn30.nid INNER JOIN term_node tn31 ON tn.nid = tn31.nid INNER JOIN term_node tn32 ON tn.nid = tn32.nid INNER JOIN term_node tn33 ON tn.nid = tn33.nid INNER JOIN term_node tn34 ON tn.nid = tn34.nid INNER JOIN term_node tn35 ON tn.nid = tn35.nid INNER JOIN term_node tn36 ON tn.nid = tn36.nid INNER JOIN term_node tn37 ON tn.nid = tn37.nid INNER JOIN term_node tn38 ON tn.nid = tn38.nid INNER JOIN term_node tn39 ON tn.nid = tn39.nid INNER JOIN term_node tn40 ON tn.nid = tn40.nid INNER JOIN term_node tn41 ON tn.nid = tn41.nid INNER JOIN term_node tn42 ON tn.nid = tn42.nid INNER JOIN term_node tn43 ON tn.nid = tn43.nid INNER JOIN term_node tn44 ON tn.nid = tn44.nid INNER JOIN term_node tn45 ON tn.nid = tn45.nid INNER JOIN term_node tn46 ON tn.nid = tn46.nid INNER JOIN term_node tn47 ON tn.nid = tn47.nid INNER JOIN term_node tn48 ON tn.nid = tn48.nid INNER JOIN term_node tn49 ON tn.nid = tn49.nid INNER JOIN term_node tn50 ON tn.nid = tn50.nid INNER JOIN node n ON tn.nid = n.nid WHERE td.vid IN (1) AND tn0.tid IN (166) AND tn1.tid IN (124) AND tn2.tid IN (123) AND tn3.tid IN (15) AND tn4.tid IN (72) AND tn5.tid IN (96) AND tn6.tid IN (77) AND tn7.tid IN (75) AND tn8.tid IN (81) AND tn9.tid IN (180) AND tn10.tid IN (21) AND tn11.tid IN (22) AND tn12.tid IN (155) AND tn13.tid IN (156) AND tn14.tid IN (76) AND tn15.tid IN (162) AND tn16.tid IN (163) AND tn17.tid IN (145) AND tn18.tid IN (122) AND tn19.tid IN (134) AND tn20.tid IN (93) AND tn21.tid IN (35) AND tn22.tid IN (24) AND tn23.tid IN (70) AND tn24.tid IN (94) AND tn25.tid IN (73) AND tn26.tid IN (16) AND tn27.tid IN (159) AND tn28.tid IN (160) AND tn29.tid IN (120) AND tn30.tid IN (71) AND tn31.tid IN (179) AND tn32.tid IN (137) AND tn33.tid IN (95) AND tn34.tid IN (138) AND tn35.tid IN (110) AND tn36.tid IN (158) AND tn37.tid IN (126) AND tn38.tid IN (74) AND tn39.tid IN (28) AND tn40.tid IN (80) AND tn41.tid IN (111) AND tn42.tid IN (37) AND tn43.tid IN (117) AND tn44.tid IN (115) AND tn45.tid IN (116) AND tn46.tid IN (98) AND tn47.tid IN (118) AND tn48.tid IN (97) AND tn49.tid IN (31) AND tn50.tid IN (32) AND n.status = 1 AND n.moderate = 0 GROUP BY td.tid ORDER BY vid, weight, name;

Drupal verzió: 
pp képe

erre mondjuk:
COUNT(DISTINCT(n.nid)) AS count

én egy taxonomy/term/1/ALL -ra gyanakszom, vagy valami jópofa modulra ami legyárt neked egy ilyen lekérdezést. Jó lenne tudni milyen a taxonomy-val kapcsolatos plusz modulok vannak fent.

nyomj egy ilyet:
wget --reject=png,jgp,jpeg,pdf,zip --domains=teoldalad.hu --recursive --level=inf --output-file=teoldalad.txt http://teoldalad.hu

Ez kigyűjti neked a méretet és az időt. Nagy oldalnál hosszú lehet ;)

pp

0
0
gazsesz képe

és ezeket találta meg:
/* Anonymous : taxonomy_filter_tf_section */ SELECT td.vid, td.tid, td.name, COUNT(DISTINCT(n.nid)) AS count FROM term_data td INNER JOIN term_node tn ON tn.tid = td.tid INNER JOIN term_node tnD

/* sysopr : taxonomy_filter_tf_section */ SELECT td.vid, td.tid, td.name, COUNT(DISTINCT(n.nid)) AS count FROM term_data td INNER JOIN term_node tn ON tn.tid = td.tid INNER JOIN term_node tnD

Taxonomy modulok:
taxonomy_blocks
_filters
_manager
_menu

Köszi

0
0

Gazsesz

gazsesz képe

Nem gyenge kutatás után lett meg a hiba egyik oka, bár egy kis szépésghibája még mindig van. Leírom, hátha más is okul belőle.

1. a főbűnös a taxonomy_filter modul volt, ő állította össze ezeket a brutál joinokat. A tesztek szerint ráadásul rosszul is fűzte össze, mert mindig 0 eredményt hozott.

A taxonomy_filter modult azért használtam, hogy az adott termékkategóriából összegyűjtse a márkaneveket és abból tovább lehessen szűrni. Ha nem szülőkategória van, akkor szépen működik is a szűrés, és az SQL is gyors, rövid. Ha viszont egy szülőkategóriát választok ki, akkor kezdi el a JOIN-okat generálni, viszont rosszul (szerintem)
A generált SQL:
SELECT td.vid, td.tid, td.name, COUNT(DISTINCT(n.nid)) AS count FROM term_data td INNER JOIN term_node tn ON tn.tid = td.tid
INNER JOIN term_node tn0 ON tn.nid = tn0.nid
INNER JOIN term_node tn1 ON tn.nid = tn1.nid
INNER JOIN node n ON tn.nid = n.nid
WHERE td.vid IN (1)
AND tn0.tid IN (169)
AND tn1.tid IN (92)
AND n.status = 1 AND n.moderate = 0 GROUP BY td.tid ORDER BY vid, weight, name

Ennek eredménye mindig 0, pedig ha csak a 169-esre, vagy a 92-esre futattom, akkor szépen adja az eredményt. Helyes eredményt az AND tn0.tid IN (169) OR tn1.tid IN (92) ad, viszont sok kategóriánál ez is bazi lassú.

Ugyanezt sokkal egyszerűbben is meg lehet oldani:
SELECT td.vid, td.tid, td.name, COUNT(DISTINCT(n.nid)) AS count FROM term_data td INNER JOIN term_node tn ON tn.tid = td.tid
INNER JOIN term_node tn0 ON tn.nid = tn0.nid
INNER JOIN node n ON tn.nid = n.nid
WHERE td.vid IN (1)
AND tn0.tid IN (169,92)
AND n.status = 1 AND n.moderate = 0 GROUP BY td.tid ORDER BY vid, weight, name
és ráadásul ez ezerszer gyorsabban lefut, mint az eredeti.

2. A következő lépés volt, hogy akkor ezt a modulban is át kell írni (soha nem csináltam még ilyet)

462-es sortól - eredeti kód:

// By replacing %d with multiple %d's we could run this query at one time (from another function above)
  $wheres = ' WHERE td.vid IN (%d)';
  foreach ($tids as $index => $tid) {
    $joins .= ' INNER JOIN {term_node} tn' . $index . ' ON tn.nid = tn' . $index . '.nid';
    $wheres .= ' AND tn' . $index . '.tid IN ('. $tid .')';
  }
  $joins .= " INNER JOIN node n ON tn.nid = n.nid";
  $wheres .= ' AND n.status = 1 AND n.moderate = 0';
  $group = ' GROUP BY td.tid';
  $order = ' ORDER BY vid, weight, name';
 
  $sql = $select . $joins . $wheres . $group . $order;
  $sql = db_rewrite_sql($sql);

..és az átiromány:

  // By replacing %d with multiple %d's we could run this query at one time (from another function above)
  $wheres = ' WHERE td.vid IN (%d)';
  $joins .= ' INNER JOIN {term_node} tn' . '0' . ' ON tn.nid = tn' . '0' . '.nid';
  $wheres .= ' AND tn' . '0' . '.tid IN (';
  foreach ($tids as $index => $tid) {
  $wheres .= $tid.',';
  }
 
  $joins .= " INNER JOIN node n ON tn.nid = n.nid";
  $wheres .= '0) AND n.status = 1 AND n.moderate = 0';
  $group = ' GROUP BY td.tid';
  $order = ' ORDER BY vid, weight, name';
 
  $sql = $select . $joins . $wheres . $group . $order;
  $sql = db_rewrite_sql($sql);

A szépséghiba
Elvileg és gyakorlatilag is gyorsan működik így a modul, még a "nagycsaládos" szülőkategóriánál is helyesen hozza a márkaneveket. Viszont, ha a márkanévre kattintok, akkor már azt írja, ki, hogy nincs beküldött post ebben a kategóriában. Asszem', ez egy következő etap lesz.

..és a megválaszolatlan kérdés
Mivel a szépséghiba eredetileg is fönnállt, ezért alapból ki volt kapcsolva a blokk megjelenítése a szülőkategóriáknál, de ennek ellenére néha mégis elindította ezt a brutal SQL-t. A miértre nem sikerült rájönni.

0
0

Gazsesz

pp képe

gazsesz képe

...csak foltkészítésben fű vagyok.
Egy bejegyzést azért betolok.

0
0

Gazsesz

pp képe

Ott a linkeken szerintem elég info van arról hogyan csinálhatsz foltot. Nem olyan bonyolult.

pp

0
0
gazsesz képe