2009-04-18 8 views
1

Ich versuche, meine MySQL-Abfragen zu optimieren, und ich brauche etwas Hilfe. Hier ist meine aktuelle Abfrage:MYSQL optimieren & Fragen

SELECT *, 
     (SELECT name FROM stores WHERE id = products.store_id) AS store_name, 
     (SELECT username FROM stores WHERE id = products.store_id) AS store_username, 
     (SELECT region_id FROM stores WHERE id = products.store_id) AS region_id, 
     (SELECT city_id FROM stores WHERE id = products.store_id) AS city_id, 
     (SELECT name FROM categories_sub WHERE id = products.subcategory_id) AS subcategory_name, 
     (SELECT name FROM categories WHERE id = category_id) AS category_name 
FROM products 
WHERE date_start <= DATE(NOW()) AND date_end >= DATE(NOW()) 

Ich bin mir ziemlich sicher, dass es schneller sein kann.

Ich habe auch ein Problem, wenn ich versuche, alle Produkte von region_id (durch Hinzufügen von etwas wie "AND region_id = MYID"), es funktioniert nicht, und ich frage mich, ob es funktioniert, und wie ?

Vielen Dank für Ihre Zeit!

Lösung

Hier ist meine letzte Abfrage, wenn es jemand helfen kann:

SELECT p.*, 
     s.name AS store_name, 
     cs.name AS subcategory_name, 
     cat.id AS category_id, cat.name AS category_name, 
     c.id AS city_id, c.name AS city_name, 
     r.id AS region_id, r.name AS region_name 
    FROM products p 
     JOIN stores s ON (s.id = p.store_id) 
     JOIN categories_sub cs ON (cs.id = p.subcategory_id) 
     JOIN categories cat ON (cat.id = cs.category_id) 
     JOIN cities c ON (c.id = s.city_id) 
     JOIN regions r ON (r.id = c.region_id) 
    WHERE DATE(NOW()) BETWEEN p.date_start AND p.date_end 

Dank!

Antwort

6

Sie müssen wirklich lernen, JOIN zu verwenden. Es ist eine grundlegende Operation für relationale Abfragen, genauso wie eine Schleife while() eine grundlegende Kontrollstruktur in den meisten Anwendungssprachen ist.

Jedes Buch oder Tutorial zu SQL sollte JOIN abdecken.

SELECT p.*, 
s.name AS store_name, s.username AS store_username, 
s.region_id, s.city_id, 
cs.name AS subcategory_name, 
c.name AS category_name 
FROM products p 
JOIN stores s ON (s.id = p.store_id) 
JOIN categories c ON (c.id = p.category_id) 
JOIN categories_sub cs ON (cs.id = p.subcategory_id) 
WHERE DATE(NOW()) BETWEEN p.date_start AND p.date_end 

Jetzt können Sie mehr Bedingungen zu Ihrer WHERE Klausel hinzuzufügen:

AND s.region_id = ?; 

Ein weiterer Kommentar ... Ich habe versucht, mithilfe des BETWEEN Prädikat klug zu sein, aber dies könnte verwirren MySQL's relativ einfacher Optimierer. MySQL hat möglicherweise eine einfachere Zeit, um Ihre ursprüngliche Syntax zu optimieren:

+0

Okkkkkk Ich denke, ich verstehe, ich habe versucht, über JOIN zu lesen, aber ich dachte, Unterabfragen wären leichter, aber gibt es einen großen Unterschied zwischen JOIN und Vijays Antwort? –

+0

Vijays Antwort ist eine implizite Verbindung. Er hat das Join-Schlüsselwort nicht explizit verwendet, aber Ihre Datenbank übersetzt SELECTING von mehreren Zielen wie diesem in einen Join. Einen Join wie den hier gezeigten zu verwenden ist einfacher. Sobald Sie mehr über Joins erfahren haben, werden Sie diese bequemer finden als Unterabfragen, die ziemlich ausführlich und viel langsamer als Joins sind. – jeffcook2150

+0

BETWEEN wird vom MySQL-Optimierer gut verarbeitet. Es gibt viele Optimierungen, die es nicht macht, aber BETWEEN sollte einen Index scannen, wenn es möglich ist, und denkt, dass dies der richtige Weg ist. BETWEEN sollte dem obigen entsprechen. – MarkR

1
SELECT A.*, B.name AS store_name, B.username as store_username, B.region_id as region_id, B.city_id AS city_id, C.name AS subcategory_name, D.name AS category_name FROM products A, stores B, categories_sub C, categories D 
WHERE B.id = A.store_id AND B.id = A.subcategory_id and C.id = A.category_id AND 
A.date_start <= DATE(NOW()) AND A.date_end >= DATE(NOW()) 
+0

Vielen Dank! Ich verstehe jetzt! –