2012-04-09 11 views
1

Ich habe eine Benutzer-Tabelle mit 450.000 Datensätze. Die Tabellenstruktur ist wie so:Mysql SubQuery Optimierung

UserID Int(11) Primary Key 
    Firstname (50) Varchar 
    Lastname (50) Varchar 

Ich brauche auch zwei andere Tabelle zu überprüfen, um zu sehen, ob der Benutzer-ID in diesen Tabellen ist. (Die Struktur ist ein bisschen anders, aber die Tabelle haben die gleiche UserID) Ich führe diese Sub-Abfrage unten, und läuft sehr langsam. Schätzen Sie einen zweiten Satz von Augen eine neue Perspektive bieten bis zu helfen, ein bisschen schneller zu laufen ...

SELECT 
`Users`.`Firstname`, 
`Users`.`Lastname`, 
`Users`.`UserID` 
FROM `Users` 
WHERE `Users`.`UserID` IN (SELECT `admin`.`UserID` FROM `admin` WHERE `admin`.`UserID`=`User`.`UserID`) 
AND `Users`.`UserID` IN (SELECT `elite`.`UserID` FROM `elite` WHERE `elite`.`UserID`=`Users`.`UserID`) 
AND `Users`.`Lastname` LIKE '%smith%' 
+0

Welche Indizes haben Sie in den Tabellen? Poste 'SHOW CREATE TABLE ...' für jede Tabelle und poste auch 'EXPLAIN SELECT ...'. –

Antwort

2

Das absolut Wichtigste wenn Abfragen in MySQL optimiert ist, um sicherzustellen, dass Sie das entsprechende Indizes . Überprüfen Sie, welche Indizes Sie haben (mit SHOW INDEX) und welche Indizes die Abfrage verwendet (mit EXPLAIN SELECT). Indizes sind absolut wichtig für eine gute Leistung, sobald Ihre Tabellen groß werden.

Insbesondere sollten Sie sicherstellen, dass Sie einen Index für die Spalte UserID in allen drei Tabellen haben. Ich würde auch vorschlagen, einen Fremdschlüssel hinzuzufügen, wenn dies in Ihrer Situation angemessen ist.

Allerdings, wenn Sie bereits überprüft haben Sie die richtigen Indizes haben, und Sie sind immer noch nicht angemessen Leistung bekommen, können Sie versuchen stattdessen statt Subselects Joins:

SELECT 
    Users.Firstname, 
    Users.Lastname, 
    Users.UserID 
FROM Users 
JOIN admin USING (UserID) 
JOIN elite USING (UserID) 
WHERE Users.Lastname LIKE '%smith%' 

Beachten Sie, dass LIKE '%smith%' nicht in der Lage ist, eine zu verwenden, Index effizient. Sie sollten vermeiden LIKE Ausdrücke, die mit einem Platzhalter wenn möglich beginnen.

+1

Es ist erwähnenswert, dass Sie keinen Index auf "% smith%" setzen können. – DCoder

+0

@DCoder: Hinzugefügt. –

1

Beginnen Sie mit Joins;

SELECT 
`Users`.`Firstname`, 
`Users`.`Lastname`, 
`Users`.`UserID` 
FROM `Users` 
INNER JOIN `admin` ON (`Users`.`UserID` = `admin`.`Users`) 
INNER JOIN `elite` ON (`Users`.`UserID` = `elite`.`UserID`) 
WHERE `Users`.`Lastname` LIKE '%smith%' 

Dann überprüfen Sie Ihre Indizes.

Sie sollten auch weg sein, dass Ihre Suche nach Nachnamen langsam sein wird, weil sie nicht am Anfang oder am Ende der Lastname Zeichenfolge verankert ist.

2

Ich denke, anstelle von Unterabfragen sollten Sie mit inneren Joins gehen ... weil Sie gerade die Benutzer-ID aus der Admin-Tabelle abrufen, Elite-Tabelle und die gleiche muss in der Benutzertabelle sein ... so weiter mit beitreten und den Unterschied sehen.

+0

stimme den obigen Kommentaren zu – Madan