LooseScan è una strategia di esecuzione per le subquery di tipo semi-join.

L'idea

Questa pagina illustra LooseScan tramite un esempio. Si supponga di cercare quei Paesi che hanno dei satelliti. E' possibile trovarli usando la query seguente (nell'interesse della semplicità ignoreremo i satelliti che appartengono a un consorzio o a più Stati):

select * from Country  
where 
  Country.code in (select country_code from Satellite)

Si supponga di avere un indice su Satellite.country_code. Utilizzandolo, si otterranno i satelliti ordinati in base al Paese di appartenenza:

loosescan-satellites-ordered-r2

La strategia LooseScan in realtà non ordina alcunché, ma ha bisogno di raggruppare. Nella figura sopra, i satelliti sono raggruppati per Paese. Per esempio, tutti i satelliti che appartengono all'Australia vengono letti in sequenza, e non si mischiano a quelli che appartengono ad altri Stati. In questo modo è più semplice selezionare un solo satellite da ogni gruppo, si può farlo leggendo una lista in base al Paese senza duplicati:

loosescan-diagram-no-where

LooseScan in azione

L'output di EXPLAIN per la query sopra riportata è il seguente:

MariaDB [world]> explain select * from Country where Country.code in (select country_code from Satellite);
+----+-------------+-----------+--------+---------------+--------------+---------+------------------------------+------+-------------------------------------+
| id | select_type | table     | type   | possible_keys | key          | key_len | ref                          | rows | Extra                               |
+----+-------------+-----------+--------+---------------+--------------+---------+------------------------------+------+-------------------------------------+
|  1 | PRIMARY     | Satellite | index  | country_code  | country_code | 9       | NULL                         |  932 | Using where; Using index; LooseScan |
|  1 | PRIMARY     | Country   | eq_ref | PRIMARY       | PRIMARY      | 3       | world.Satellite.country_code |    1 | Using index condition               |
+----+-------------+-----------+--------+---------------+--------------+---------+------------------------------+------+-------------------------------------+

Riassunto

  • LooseScan evita di produrre combinazioni di record duplicate mettendo per prima la tabella della subquery e utilizzando il suo indice per selezionare un unico record da diversi duplicati
  • Di conseguenza, LooseScan è applicabile solo se la subquery assomiglia alla seguente:
expr IN (SELECT tbl.parte_di_indice1 FROM tbl ...)

oppure:

expr IN (SELECT tbl.parte_di_indice2 FROM tbl WHERE tbl.parte_di_indice1=cost AND ...)
  • LooseScan è in grado di gestire le subquery correlate
  • LooseScan può essere disattivando impostando il flag loosescan=off in @@optimizer_switch.

Commenti

Sto caricando i commenti......