2010-07-27 19 views
12

Ho bisogno di interrogare un'istruzione delete per la stessa tabella in base alle condizioni della colonna dalla stessa tabella per una sottoquery correlata.Elimina istruzione in una stessa tabella

Impossibile eseguire direttamente un'istruzione delete e controllare una condizione per la stessa tabella in mysql per una sottoquery correlata.

Desidero sapere se l'utilizzo della tabella temporanea influirà sulla memoria/prestazioni di mysql?

Qualsiasi aiuto sarà molto apprezzato.

Grazie.

+0

Perché non puoi 'eseguire direttamente un'istruzione di cancellazione e controllare una condizione per la stessa tabella'? –

risposta

13

tua domanda in realtà non è chiaro, ma direi di avere una subquery correlata e hai problemi facendo un SELECT dalla stessa tabella che viene bloccato dal DELETE. Ad esempio per eliminare tutto tranne la revisione più recente di un documento:

DELETE FROM document_revisions d1 WHERE edit_date < 
    (SELECT MAX(edit_date) FROM document_revisions d2 
    WHERE d2.document_id = d1.document_id); 

Questo è un problema per MySQL.

Molti esempi di questi tipi di problemi possono essere risolti utilizzando MySQL multi-tavolo eliminare sintassi:

DELETE d1 FROM document_revisions d1 JOIN document_revisions d2 
    ON d1.document_id = d2.document_id AND d1.edit_date < d2.edit_date; 

Ma queste soluzioni sono meglio progettati caso per caso, quindi, se si modifica la tua domanda e sii più specifico sul problema che stai cercando di risolvere, forse possiamo aiutarti.

In altri casi potresti avere ragione, l'utilizzo di una tabella temporanea è la soluzione più semplice.

+0

Thanks bill, Sì, hai capito bene, sto avendo problemi nell'esecuzione dell'eliminazione di subquery correlata in mysql. Se uso la sintassi di cancellazione multi-table, prendo subito questa query nel log delle query lente. (supponete di avere record 50K nella tabella che state cancellando, se faccio una verifica della condizione usando la sintassi multi-delete, ottengo immediatamente questa query nel log lento della query). Quindi sono andato al concetto di tabella temporanea, la mia domanda è che la tabella temporanea influirà sulla memoria/prestazioni di mysql? – Sharpeye500

+0

Ovviamente una tabella temporanea richiede una certa quantità di risorse, ma tieni presente che MySQL crea tabelle temporanee al volo per le query tutte le volte. E la tabella temporanea viene liberata quando si chiude la corrente connessione mysql, quindi sono piuttosto di breve durata. –

+0

Tuttavia, suggerirei di indagare sul motivo per cui l'eliminazione di più tabelle è stata così lenta. È abbastanza semplice scrivere un SELECT equivalente che faccia lo stesso join, e quindi è possibile utilizzare EXPLAIN per analizzare il piano di ottimizzazione per SELECT (MySQL EXPLAIN non supporta DELETE). Potrebbe essere possibile creare l'indice di copertura corretto per eseguire rapidamente DELETE. –

0

È possibile eliminare dalla stessa tabella. DELETE è la seguente

DELETE FROM table_name 
WHERE some_column=some_value 
1

non è possibile eseguire direttamente una dichiarazione di cancellazione e verificare una condizione per la stessa tabella

Certo che puoi. Se si desidera eliminare dal table1 mentre si verifica la condizione che col1 = 'somevalue', si potrebbe fare questo:

DELETE 
    FROM table1 
WHERE col1 = 'somevalue' 

EDIT
eliminare utilizzando una subquery correlata, vedere il seguente esempio:

create table project (id int); 
create table emp_project (id int, project_id int); 

insert into project values (1); 
insert into project values (2); 
insert into emp_project values (100, 1); 
insert into emp_project values (200, 1); 

/* Delete any project record that doesn't have associated emp_project records */ 
DELETE 
    FROM project 
WHERE NOT EXISTS 
    (SELECT * 
     FROM emp_project e 
     WHERE e.project_id = project.id); 


/* project 2 doesn't have any emp_project records, so it was deleted, now 
    we have 1 project record remaining */ 
SELECT * FROM project; 

Result: 
id 
1 
+0

oops ... mi hai fatto sembrare stupido :-) ma ho perso questo punto, vale a dire. per subqueries DELETE FROM DOVE IN (SELECT FROM DOVE NOT IN (SELECT DA GROUP BY ORDER BY ) Questa query richiede più tempo quando i record sono alti, la mia domanda è fare questo usando la tabella temporanea influenzerà il livello di prestazioni di mysql o migliorerà se questo viene fatto usando la tabella temporanea ad esempio ottenere i valori di subquery e inserirli in una tabella temporanea ed eseguire un'istruzione di cancellazione dove la condizione IN verrà controllata con selezionare col1 da temp. – Sharpeye500

+0

@Sharpeye - Scusa, no intendo farti sembrare pazzo, ho pensato che fosse la tua vera domanda. Ad ogni modo, sarebbe bello poter pubblicare un esempio di dati, ovvero mostrarci i record esistenti prima e i record che ci si aspetta vengano eliminati. Allora saremo in grado di aiutare di più. – dcp

+0

Grazie per aver corretto la mia domanda, ho modificato ora. – Sharpeye500

0

Creare una tabella temporanea con i valori che si desidera eliminare, quindi aggiungerla alla tabella durante l'eliminazione. In questo esempio ho una tabella "Giochi" con una colonna ID. Eliminerò gli ID superiori a 3. Raccoglierò gli obiettivi in ​​una tabella temporanea per poterli poi segnalare in seguito.

DECLARE @DeletedRows TABLE (ID int) 

insert 
    @DeletedRows 
     (ID) 
select 
    ID 
from 
    Games 
where 
    ID > 3 


DELETE 
    Games 
from 
    Games g 
join 
    @DeletedRows x 
    on x.ID = g.ID 
+1

Grazie carter, ma questo influenzerà le prestazioni di MySQL? per es. dì se hai 1000 utenti sul tuo sito, se tutti loro iniziano a creare tabelle temporanee sul loro login, cosa accadrà alla cache della tabella/memoria della tabella, aumenterà corretta? – Sharpeye500

+0

Sta solo creando una tabella in memoria. Utilizzerà più risorse rispetto all'eliminazione normale delle righe, ma se si desidera segnalare i record cancellati, è l'unico modo. Usa la memoria solo per memorizzare gli ID dei record che stai per eliminare. –

19

È possibile creare mysql per la tabella temporanea avvolgendo la query "where" come inline dalla tabella.

Questa query originale vi darà il temuto "Non è possibile specificare tabella di destinazione per l'aggiornamento dalla clausola":

DELETE FROM sametable 
WHERE id IN (
    SELECT id FROM sametable WHERE stuff=true 
) 

riscrittura in modo da utilizzare temperatura inline diventa ...

DELETE FROM sametable 
WHERE id IN (
SELECT implicitTemp.id from (SELECT id FROM sametable WHERE stuff=true) implicitTemp 
) 
+0

Ho trovato che questo ha provocato una query molto lenta. Non sono sicuro di quanto sia lento perché mi sono arreso dopo 1-3 minuti. Usare un JOIN come suggerito da Bill Karwin era di circa 100ms. – phylae

Problemi correlati