ho dati gerarchici in un modello di serie nidificato (tabella: progetti):Mysql: Ottimizzazione trovare super-nodo albero set nidificato
mio tavolo (progetti):
id, lft, rgt
1, 1, 6
2, 2, 3
3, 4, 5
4, 7, 10
5, 8, 9
6, 11, 12
7, 13, 14
...
Abbastanza stampata:
1
2
3
4
5
6
7
Per trovare il nodo più vicino eccellente del nodo 3 (conoscendo il suo valore LFT), posso fare
explain
SELECT projects.*
FROM projects
WHERE 4 BETWEEN projects.lft AND projects.rgt
Quale mi dà un elenco dei progetti nel percorso fino al nodo 3. Quindi raggruppando e trovando MAX (projects.lft) dei risultati, ottengo il super-nodo più vicino. Tuttavia, non posso sembrare che questa query sia veloce, non userà gli indici che ho definito. SPIEGARE dice:
+----+-------------+----------+-------+----------------+----------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+-------+----------------+----------+---------+------+------+--------------------------+
| 1 | SIMPLE | projects | index | lft,rgt,lftRgt | idLftRgt | 12 | NULL | 10 | Using where; Using index |
+----+-------------+----------+-------+----------------+----------+---------+------+------+--------------------------+
Mysql capisce quello dell'indice da usare, ma ha ancora a scorrere tutti 10 righe (o 100k nel mio tabella effettiva).
Come posso ottenere MySql per ottimizzare correttamente questa query? Includo uno script di test sotto.
DROP TABLE IF EXISTS projects;
CREATE TABLE projects (
id INT NOT NULL ,
lft INT NOT NULL ,
rgt INT NOT NULL ,
PRIMARY KEY (id)
) ENGINE = MYISAM ;
ALTER TABLE projects ADD INDEX lft (lft);
ALTER TABLE projects ADD INDEX rgt (rgt);
ALTER TABLE projects ADD INDEX lftRgt (lft, rgt);
ALTER TABLE projects ADD INDEX idLftRgt (id, lft, rgt);
INSERT INTO projects (id,lft,rgt) VALUES (1,1,6);
INSERT INTO projects (id,lft,rgt) VALUES (2,2,3);
INSERT INTO projects (id,lft,rgt) VALUES (3,4,5);
INSERT INTO projects (id,lft,rgt) VALUES (4,7,10);
INSERT INTO projects (id,lft,rgt) VALUES (5,8,9);
INSERT INTO projects (id,lft,rgt) VALUES (6,11,12);
INSERT INTO projects (id,lft,rgt) VALUES (7,13,14);
INSERT INTO projects (id,lft,rgt) VALUES (8,15,16);
INSERT INTO projects (id,lft,rgt) VALUES (9,17,18);
INSERT INTO projects (id,lft,rgt) VALUES (10,19,20);
explain
SELECT projects.*
FROM projects
WHERE 4 BETWEEN projects.lft AND projects.rgt
Tu amico mio, sei un genio! Hai appena salvato il nostro server DB dal pensionamento anticipato. Stai andando nella lista dei crediti (yast.com), quando ne facciamo uno :) – Joernsn
Grazie :) Non dimenticare di aggiungere un collegamento al mio blog (http://explainextended.com) :) – Quassnoi