2014-02-24 24 views
5
explain 
SELECT COUNT(*) AS Count, CreatedBy 
FROM `Notes` 
INNER JOIN Users ON UserID = CreatedBy 
INNER JOIN UserRoles ON URoleID = RoleID AND RoleID = 1 
WHERE NoteVisible = 1 AND NoteText NOT LIKE '%SOME KEYWORD%' 
     AND Created BETWEEN '2014-02-24 00:00:00' AND '2014-02-24 23:59:59' 
GROUP BY CreatedBy 

enter image description hereMySQL zwischen zwei Datetimes nicht verwendet INDEX

Wie Sie ref sehen NULL ist und geht durch Zeilen statt nur Reihe durchlaufen. Jetzt für dieses Beispiel ist das schnell, aber wenn ich einen Bereich von 1-2 Monaten mache, wird die Zeile > 10000 und es verlangsamt die Seite viel und stopt Tabellen.

HINWEIS Wenn ich entfernen die 00.00.00 und 23.59.59 dann verwendet sie Index geht es nur durch 1 Zeile, aber ich brauche alle Daten für den ganzen Tag wählen bei 00 starten : 00 und endend bei 23:59.

Bitte helfen Sie mir diese Anfrage umstrukturieren, um dieses Problem zu beheben oder mögliche Lösungen vorschlagen. Danke.

EDIT

Ersetzen ZWISCHEN von < oder > oder < = oder > = hat das Problem

+0

Was passiert, wenn Sie ersetzen 'BETWEEN' für' (‚2014.02.24‘ <= Erstellt UND Erstellt < ‚2014- 02-25 ') '? – vadchen

+0

Bereits verwendet, dass in verschiedenen Variationen immer noch nicht Index – GGio

+0

verwenden Bitte Struktur von Tabellen, oder fügen Sie mindestens Präfixe zu Spaltennamen in der Abfrage, es ist schwer zu erraten, welche Spalte zu welcher Tabelle gehören. Gehört 'NoteVisible' zu' Notes'? – krokodilko

Antwort

4

Diese Abfrage verwendet der Index nicht beheben.
Der Auswahltyp ist range, verwendete Schlüssel Created

Für Bereichstypen, die ref Spalte immer null ist,
siehe Dokumentation: http://dev.mysql.com/doc/refman/5.7/en/explain-output.html#jointype_range

Bereich

Nur Zeilen, werden in einem bestimmten Bereich abgerufen, wobei ein Index verwendet wird, um die Zeilen auszuwählen. Die Schlüsselspalte in der Ausgabezeile gibt an, welcher Index verwendet wird. Der key_len enthält den längsten Schlüsselteil, der verwendet wurde. Die Ref-Spalte ist für diesen Typ NULL.

(Hervorhebung von mir)

+0

, aber es gibt keine 23 Zeilen in diesem Bereich, wenn ich entferne, erkläre es gibt nur 1 Zeile zurück. – GGio

+2

Dies ist nur eine Schätzung - MySql denkt, dass es 23 Zeilen gibt. Es prüft nicht die genaue Anzahl der Zeilen während der Parserphase, es wird nur geschätzt. Aber in Anbetracht dessen denkt es, dass es besser ist, diesen Index zu verwenden und 23 Zeilen zu verbinden, als den Primärschlüssel zu verwenden und X-Zeilen zu verbinden. – krokodilko

+0

Gibt es eine Möglichkeit, die Verlangsamung zu beheben? – GGio

0

, wenn Sie ein Datetime-Feld in einem greater_than/less_than Vergleich mit Strings vergleichen. Wenn Sie eine Umwandlung oder Funktion (wie UNIX_TIMESTAMP()) verwenden und auch die anderen Daten in unixtimestamp umwandeln, würde das zwar den Zweck erfüllen, aber die Verwendung des Indexes zerstören. Vielleicht wäre eine bessere Lösung, das Datum als Unix-Timestamp in der Tabelle zu speichern und einen Index darauf zu setzen.

andersrum, können Sie „Limit“, um Ihre SQL hinzufügen arbeitete auch für mich

Verwandte Themen