Ho una tabella che ha una chiave esterna in una tabella che memorizza alcuni dati BLOB. Quando eseguo un join interno sui tavoli con una condizione nella tabella principale, il tipo di join va da "index" a "ALL". Vorrei evitare questo perché la mia tabella blob è dell'ordine di decine di gigabyte. Come posso evitarlo?Come evitare una scansione completa della tabella con questo join interno di base?
Ecco unirsi alla quella interna di base:
EXPLAIN SELECT m.id, b.id, b.data
FROM metadata m, blobstore b
WHERE m.fkBlob = b.id;
1, 'SIMPLE', 'm', 'index', 'fk_blob', 'fk_blob', '4', '', 1, 'Using index'
1, 'SIMPLE', 'b', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'blob_index.m.fkBlob', 1, ''
Qui ho aggiungere una condizione sul tavolo principale:
EXPLAIN SELECT m.id, b.id, b.data
FROM metadata m, blobstore b
WHERE m.fkBlob = b.id AND m.start < '2009-01-01';
1, 'SIMPLE', 'b', 'ALL', 'PRIMARY', '', '', '', 1, ''
1, 'SIMPLE', 'm', 'ref', 'fk_blob,index_start', 'fk_blob', '4', 'blob_index.b.id', 1, 'Using where'
Si noti che l'ordine in cui sono elencate le tabelle è cambiato. Ora sta eseguendo una scansione completa della tabella sulla tabella blob a causa di una condizione che ho aggiunto per quanto riguarda la tabella principale.
Ecco lo schema:
DROP TABLE IF EXISTS `blob_index`.`metadata`;
CREATE TABLE `blob_index`.`metadata` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`fkBlob` int(10) unsigned NOT NULL,
`start` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_blob` (`fkBlob`),
KEY `index_start` (`start`),
CONSTRAINT `fk_blob` FOREIGN KEY (`fkBlob`) REFERENCES `blobstore` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS `blob_index`.`blobstore`;
CREATE TABLE `blob_index`.`blobstore` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`data` mediumblob NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Vostro diritto, ho buttato alcuni dati lì, ho eseguito la tabella di analisi su entrambe le tabelle e ora il primo join è di tipo range sul meta-table. – Fredrick