Devo selezionare le righe dalla tabella BUNDLES che hanno uno dei diversi valori SAP_STATE_ID. Tali valori dipendono dal fatto che il rispettivo stato SAP debba essere esportato o meno.Perché la subquery e il join sono così lenti
Questa query viene eseguita molto velocemente (non v'è indice sul campo SAP_STATE_ID) -
SELECT b.* FROM BUNDLES b WHERE b.SAP_STATE_ID IN (2,3,5,6)
Ma ... mi piacerebbe andare a prendere elenco di ID in modo dinamico, in questo modo:
SELECT b.* FROM BUNDLES b
WHERE b.SAP_STATE_ID IN
(SELECT s.SAP_STATE_ID FROM SAP_STATES s WHERE s.EXPORT_TO_SAP = 1)
E ahi, questa query sta prendendo improvvisamente troppo tempo. Mi aspetto che il server SQL esegua prima la sottoquery (non dipende da alcunché dalla query principale) e quindi esegue tutto come nel mio primo esempio. Ho provato a riscriverlo per usare joins anziché subquery:
SELECT b.* FROM BUNDLES b
JOIN SAP_STATES s ON (s.SAP_STATE_ID = b.SAP_STATE_ID)
WHERE s.EXPORT_TO_SAP = 1
ma ha le stesse scarse prestazioni. Sembra che esegua la subquery per ogni riga della tabella BUNDLES o qualcosa del genere. Non sono molto bravo a leggere i piani di esecuzione, ma ci ho provato. Dice che il costo dell'81% è per la scansione dell'indice della chiave primaria di BUNDLES (non ho idea del perchè dovrebbe fare una cosa del genere, c'è un campo BUNDLE_ID definito come PRIMARY KEY, ma non appare affatto nella query ...)
Qualcuno ha una spiegazione perché SQL Server è così "stupido"? C'è un modo per ottenere ciò che voglio con buone prestazioni ma senza la necessità di fornire un elenco statico di SAP_STATE_IDs?
copione per entrambe le tabelle e rilevanti indici - piano http://mab.to/xbYiI0wKj
di esecuzione per la versione subquery - http://mab.to/8Qh6gpdYZ
piano di query per la versione con join - http://mab.to/YCqeGCUbr
(per qualche motivo queste due piani sembra lo stesso ed entrambi suggeriscono di creare l'indice BUNDLES.SAP_STATE_ID, che è già presente)
Avete un indice su SAP_STATES.SAP_STATE_ID? –
sì, è una chiave primaria in realtà – lot
Quanto tempo impiega il subquery per eseguirlo da solo? – DavidG