Einzelnen Beitrag anzeigen
  #14  
Alt 31.10.2010, 11:53:00
droehn droehn ist offline
Anfänger
 
Registriert seit: Oct 2010
Alter: 51
Beiträge: 19
AW: COUNT mit JOINs und sub-queries kriechend langsam

Ich war so frei, in der Tabelle 'salesprices' auch gleich die Indexe anzupassen:

Code:
ALTER TABLE salesprices
 DROP INDEX artikleid,
 DROP INDEX deleted,
 ADD INDEX idx_art_val_del (artikleid,validfrom,deleted);
Und schon läuft's rund 40% schneller :-) Ich arbeite im Moment auf einem Server der etwas mehr Bums als mein Laptop hat, deswegen kann ich die Zeiten nicht direkt vergleichen. Aber vor den neuen Indizies dauerte die Abfrage 5,2 Sekunden, jetzt 3,2 Sekunden. Das ist doch schonmal was :-)

Allerdings ist die Anzahl 'rows' in der Tabelle 'labels' von 2 auf 18 hochgesprungen. Hat das überhaupt irgendeine nützliche Bedeutung? Ausserdem steht auf der Zeile 'p15' unter 'ref' neu ein 'const'. Ich nehme an, das ist damit zu erklären, dass im Moment alle 'validfrom' und 'deleted' Werte unter p15 dieselben sind.

Ergebnis EXPLAIN:
Code:
+----+--------------------+-------+--------+------------------------------------------+---------------------+---------+--------------------------------------------------+-------+--------------------------+
| id | select_type        | table | type   | possible_keys                            | key                 | key_len | ref                                              | rows  | Extra                    |
+----+--------------------+-------+--------+------------------------------------------+---------------------+---------+--------------------------------------------------+-------+--------------------------+
|  1 | PRIMARY            | p12   | index  | deleted,idx_art_del_sup                  | idx_art_del_sup     | 9       | NULL                                             | 61270 | Using where; Using index |
|  1 | PRIMARY            | t1    | eq_ref | PRIMARY,deleted,idx_id_deleted           | PRIMARY             | 4       | store_dwh.p12.artikleid                          |     1 | Using where              |
|  1 | PRIMARY            | r20   | eq_ref | PRIMARY,deleted                          | PRIMARY             | 4       | store_dwh.p12.supplierid                         |     1 |                          |
|  1 | PRIMARY            | p13   | ref    | supplierid,idx_art_sup_val_del           | idx_art_sup_val_del | 8       | store_dwh.t1.id,store_dwh.r20.id                 |     1 | Using index              |
|  1 | PRIMARY            | p15   | ref    | idx_art_val_del                          | idx_art_val_del     | 5       | const,store_dwh.t1.id                            |     1 | Using index              |
|  1 | PRIMARY            | p11   | ref    | deleted,artikleid,lang                   | artikleid           | 4       | store_dwh.t1.id                                  |    18 |                          |
|  3 | DEPENDENT SUBQUERY | p15b  | ref    | validfrom,idx_art_val_del                | idx_art_val_del     | 5       | store_dwh.t1.deleted,store_dwh.p15.artikleid     |     1 | Using where; Using index |
|  2 | DEPENDENT SUBQUERY | p13b  | ref    | supplierid,validfrom,idx_art_sup_val_del | idx_art_sup_val_del | 8       | store_dwh.p13.artikleid,store_dwh.p13.supplierid |     1 | Using where; Using index |
+----+--------------------+-------+--------+------------------------------------------+---------------------+---------+--------------------------------------------------+-------+--------------------------+

SHOW CREATE TABLE (nur noch der Index Teil - Rest bleibt sich ja stets gleich)
Code:
+---------------+------------------------------------------------------------------------------+
| purchprices   | PRIMARY KEY (`id`),
|               | KEY `supplierid` (`supplierid`),
|               | KEY `validfrom` (`validfrom`)
|               | KEY `idx_art_sup_val_del` (`artikleid`,`supplierid`,`validfrom`,`deleted`)
|               | ) ENGINE=MyISAM AUTO_INCREMENT=61372 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC
+---------------+------------------------------------------------------------------------------+
| salesprices   | PRIMARY KEY (`id`),
|               | KEY `validfrom` (`validfrom`)
|               | KEY `idx_art_val_del` (`deleted`,`artikleid`,`validfrom`)
|               | ) ENGINE=MyISAM AUTO_INCREMENT=61371 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC
+---------------+------------------------------------------------------------------------------+
Die Subqueries haben den Sinn, abhängig vom aktuellen Datum immer die gültigen Preise anzuzeigen. Da ich aber auch zukünftige Preisänderungen eingeben kann, darf die Abfrage nicht einfach SELECT MAX oder lauten, sonst erhalte ich Preise, die noch nicht gültig sind; < time() geht auch nicht, da mir sonst Preise der vor-vor-vor-letzten Preisänderung mit angezeigt werden.

Beispiel: die letzte Preiserhöhung auf dem Artikel "Holzwurm" war am ('validfrom') 1.1.2010, die vorletzte am 1.1.2009 und die nächste am 1.1.2011. Die Abfrage muss lauten: Zeig mir den Preis der mit heutigem Datum ('time()' = 31.10.2010) gültig ist.

Grüsse
David
Mit Zitat antworten