Nel manuale MySQL c'è una pagina su index hinting che indica che è possibile specificare l'indicizzazione dell'indice per parti specifiche della query.Come funziona Index Scope in Mysql?
È possibile specificare l'ambito di un suggerimento indice aggiungendo una clausola
FOR
al suggerimento. Ciò fornisce un controllo più dettagliato sulla selezione dell'ottimizzatore di un piano di esecuzione per varie fasi dell'elaborazione della query. Per influenzare solo gli indici utilizzati quando MySQL decide come trovare le righe nella tabella e come elaborare i join, utilizzareFOR JOIN
. Per influenzare l'utilizzo dell'indice per l'ordinamento o il raggruppamento di righe, utilizzareFOR ORDER BY
oFOR GROUP BY
.
Tuttavia, ci sono poche o nessuna informazione su come funziona o cosa fa effettivamente nell'ottimizzatore MySQL. Inoltre, in pratica sembra essere trascurabile nel migliorare effettivamente qualsiasi cosa.
Ecco una query di prova e che cosa spiegare dice sulla query:
SELECT
`property`.`primary_id` AS `id`
FROM `California` `property`
USE INDEX FOR JOIN (`Zipcode Bedrooms`)
USE INDEX FOR ORDER BY (`Zipcode Bathrooms`)
INNER JOIN `application_zipcodes` `az`
ON `az`.`application_id` = '18'
AND `az`.`zipcode` = `property`.`zipcode`
WHERE `property`.`city` = 'San Jose'
AND `property.`zipcode` = '95133'
AND `property`.property_type` = 'Residential'
AND `property`.`style` = 'Condominium'
AND `property`.`bedrooms` = '3'
ORDER BY `property`.`bathrooms` ASC
LIMIT 15
;
spiego:
EXPLAIN SELECT `property`.`primary_id` AS `id` FROM `California` `property` USE INDEX FOR JOIN (`Zipcode Bedrooms`) USE INDEX FOR ORDER BY (`Zipcode Bathrooms`) INNER JOIN `application_zipcodes` `az` ON `az`.`application_id` = '18' AND `az`.`zipcode` = `property`.`zipcode` WHERE `property`.`city` = 'San Jose' AND `property.`zipcode` = '95133' AND `property`.property_type` = 'Residential' AND `property`.`style` = 'Condominium' AND `property`.`bedrooms` = '3' ORDER BY `property`.`bathrooms` ASC LIMIT 15\g
+------+-------------+----------+--------+---------------+---------+---------+------------------------------------+------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+----------+--------+---------------+---------+---------+------------------------------------+------+----------------------------------------------------+
| 1 | SIMPLE | Property | ref | Zip Bed | Zip Bed | 17 | const,const | 2364 | Using index condition; Using where; Using filesort |
| 1 | SIMPLE | az | eq_ref | PRIMARY | PRIMARY | 7 | const,Property.zipcode | 1 | Using where; Using index |
+------+-------------+----------+--------+---------------+---------+---------+------------------------------------+------+----------------------------------------------------+
2 rows in set (0.01 sec)
Quindi, per riassumere sto fondamentalmente chiedo come la portata indice è stato pensato per essere usato, in quanto ciò non sembra fare nulla quando aggiungo o rimuovo la riga USE INDEX FOR ORDER BY (Zipcode Bathrooms)
.
Essenzialmente era un modo per creare una relazione uno a molti tra un elenco di codici di avviamento postale che avevo. [Hai effettivamente commentato quel problema che stavo avendo e questo risultato sembra essere il risultato più veloce.] (Http: // StackOverflow.it/questions/32256402/sql-performance-using-or-is-slow-than-in-quando-using-order-by) Questa query nella domanda è in realtà piuttosto veloce se sta usando l'indice corretto, tuttavia l'ottimizzatore prova a scegliere quello sbagliato, causando un filesort. Inoltre non riesco a rimuovere nessuno degli indici poiché sono entrambi necessari per l'ordinamento. – Dbeazy
Non è stato possibile modificare nuovamente il mio ultimo commento. Hai detto: "I bagni non sono molto selettivi; non c'è molto da guadagnare anche se sarebbe possibile. Anche se questo è vero in un caso di dichiarazione where, ci sono molte righe, quindi usarlo come indice per l'ordine è molto più veloce di quanto sarebbe quando usando un indice su 'Bedrooms'. Volevo anche notare che ho anche provato ad usare un gigantesco Union All per i codici di avviamento postale, ed era davvero veloce, ma questo doveva essere gestibile da altri sviluppatori diversi da me, quindi ho pensato che l'astrazione contorta per un minore aumento di velocità rispetto alla corrente fosse non ne vale la pena. – Dbeazy