MySQL: Warum vergleicht Primärschlüssel mit einer zufällig generierten Zahl, die den Index nicht verwendet?

8

Es wird versucht, eine zufällige Zeile aus einer Tabelle basierend auf dem automatisch inkrementierten Primärschlüssel ohne Lücken auszuwählen.

Das Tabellenschema:

%Vor%

Abfragen:

1 / explain select * from testTable where id = ceil(Rand()*10) limit 1 ;

Ссылка

Ergebnis:

%Vor%

2 / explain select * from testTable where id = 7 limit 1 ;

Ссылка

Ergebnis:

%Vor%

Warum verwendet Abfrage # 1 den Index nicht, wenn ceil(rand()*10) idealerweise zu einer Konstante ausgewertet werden soll, die dann mit dem Primärschlüssel verglichen werden kann? Sollte der Optimierer nicht so funktionieren? Oder fehlt mir hier etwas Offensichtliches?

    
DhruvPathak 11.09.2012, 07:42
quelle

2 Antworten

6

Der Schlüssel kann nicht mit dieser Abfrage verwendet werden, weil RAND() für jede Zeile aufgerufen wird und jedes Mal ein anderer Wert zurückgegeben wird.

Sie können stattdessen diesen Code ausprobieren:

%Vor%

Er berechnet zuerst einen zufälligen Wert und weist ihn einer Variablen zu und verwendet sie dann in der Abfrage.
Wie von Aneroid gezeigt, ist LIMIT 1 nutzlos: Da die Bedingung für den Primärschlüssel gilt, gibt die Abfrage niemals mehr als eine Zeile zurück.

Bei dieser Abfrage lautet die Ausgabe:

%Vor%     
Jocelyn 11.09.2012, 07:49
quelle
3

Aus der MySQL-Dokumentation für RAND() :

  

RAND() in einer WHERE -Klausel wird jedes Mal neu ausgewertet, wenn WHERE ausgeführt wird.

So wird der Primärschlüssel nicht mit einer Konstanten verglichen, sondern es ändert sich jedes Mal (in diesem Fall für jede Zeile). Wenn Sie die LIMIT 1 in Ihrer Abfrage entfernen, sehen Sie mehr Zeilen mit den verschiedenen PKs, die übereinstimmen - was das Verhalten "jedes Mal neu bewertet" anzeigt.

Bearbeiten: Siehe Jocelyns Beispiel als eine Möglichkeit, zuerst die Zufallszahl zu generieren und dann eine Zeile mit der passenden PK id zu erhalten (die LIMIT 1 wird nicht benötigt, btw). Ähnlich in Najzeros Kommentar angegeben.

    
aneroid 11.09.2012 08:01
quelle

Tags und Links