2013-02-22 4 views
7

Ich habe diese Tabelle:Mysql Abfrage Dont't verwendet Index, wenn es Variablen in WHERE

CREATE TABLE `ClientesHora_copy` (
`dia` varchar(6) default NULL, 
`hora` varchar(2) default NULL, 
`sit` varchar(17) default NULL, 
`nodo` varchar(6) default NULL, 
`clientes` decimal(41,0) default NULL, 
`segundos` double default NULL, 
`llamadas` decimal(41,0) default NULL, 
`fecha` datetime default NULL, 
KEY `nodo_fecha` (`nodo`,`fecha`), 
KEY `nodo` (`nodo`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 

und diese Abfrage:

SET @sitio= 'ABA000'; 
SET @horaini='2013-02-12 15:18:00'; 
SET @horafin='2013-02-12 20:36:00';  
    EXPLAIN SELECT nodo,sit,clientes,segundos,llamadas,fecha,hora,@horaini AS horaini,@horafin AS horafin 
     FROM `ClientesHora_copy` 
     WHERE 
     nodo [email protected] 
     AND 
     fecha BETWEEN DATE_SUB(DATE_FORMAT(@horaini, "%Y-%m-%d %H:00:00"), INTERVAL 7 DAY) 
      AND DATE_SUB(DATE_FORMAT(@horafin, "%Y-%m-%d %H:00:00"), INTERVAL 7 DAY) 

Ich habe dies in

id select_type table    type possible_keys key  key_len ref  rows Extra   
------ ----------- ----------------- ------ ------------- ------ ------- ------ ------- ------------- 
1 SIMPLE  ClientesHora_copy ALL  (NULL)   (NULL) (NULL) (NULL) 2716460 Using where 
erklären

Aber wenn ich nicht die Variable @sitio verwende (aber die Variablen @horaini, @horafin):

ich dieses:

id select_type  table    type possible_keys key   key_len ref  rows Extra 
------ ----------- ----------------- ------ --------------- ---------- ------- ------ ------ ------------- 
1 SIMPLE   ClientesHora_copy range nodo_fecha,nodo nodo_fecha 18  (NULL)  1 Using where 

Jede Idee, warum Mysql doesnt den Index mit der @sitio Variable verwenden, aber es funktioniert mit @fechaini und @fechafin?

Danke!

+2

Das Problem ist nicht das Fehlen eines "konstanten" Wertes (wie die ausgewählte Antwort anzeigt). Es ist ziemlich einfach zu demonstrieren, dass MySQL einen Index "const" ref mit einer Benutzervariablen verwendet. Das Problem ist der Zeichensatz; Die Benutzervariable hat wahrscheinlich einen anderen Zeichensatz als die Spalte. Wir können die 'CONVERT()' -Funktion verwenden, um zwischen verschiedenen Zeichensätzen zu konvertieren. – spencer7593

Antwort

8

Die wahrscheinlichste Erklärung ist, dass die Spalte nodo Zeichentyp ist und character_set_connection nicht mit dem für die Spalte angegebenen Zeichensatz übereinstimmt.

Wenn die Säule mit latin1 characterset festgelegt, versucht:

WHERE nodo = CONVERT(@sitio USING latin1) 

Als Demonstration, mit UTF-8, erklärt Ausgabe zeigt keinen Index zur Verfügung:

EXPLAIN SELECT t.* FROM mytable t WHERE t.foo = CONVERT(@foo USING utf8) 
                    ^^^^ 
id select_type table type possible_keys key key_len ref rows Extra   
-- ----------- ----- ---- ------------- ------ ------- ------ ---- ----------- 
1 SIMPLE  t  ALL (NULL)  (NULL) (NULL) (NULL) 3 Using where 

Aber mit latin1, explain output zeigt an, dass der Index verfügbar ist (und verwendet wird):

EXPLAIN SELECT t.* FROM mytable t WHERE t.foo = CONVERT(@foo USING latin1) 
                    ^^^^^^  
id select_type table type possible_keys key key_len ref rows Extra   
-- ----------- ----- ---- ------------- ------ ------- ------ ---- ----------- 
1 SIMPLE  t  ref t_ix   t_ix 13  const  1 Using where 
+1

anscheinend war das das Problem, ich änderte die Variablendeklaration in SET @ sitio = CONVERT ('AA000' VERWENDUNG latin1); und die Abfrage ist jetzt wirklich schnell. Vielen Dank! – Alejandro

+0

Danke, das hat mein Problem auch gelöst! –

Verwandte Themen