2011-06-19 29 views
2

我的數據庫擁有20000條記錄的表名稱事務。當我運行此查詢緩慢依賴的子查詢 - 如何提高性能?

SELECT T1.* FROM transactions AS T1 
WHERE T1.ppno IN 
    (SELECT T2.PPNO FROM transactions AS T2 
    WHERE T2.ppno = T1.ppno 
    HAVING COUNT(T2.ppno) = $doublescount) 
ORDER BY T1.ppno,T1.numb 

它需要至少3分鐘運行....如何加快此查詢。 PLZ幫助

編輯1: show create table transactions回報爲

CREATE TABLE `transactions` (
    `eidx` int(10) unsigned NOT NULL, 
    `numb` int(10) unsigned NOT NULL, 
    `date` date NOT NULL, 
    `time` varchar(45) NOT NULL, 
    `name` varchar(45) NOT NULL, 
    `add1` varchar(45) NOT NULL, 
    `add2` varchar(45) NOT NULL, 
    `city` varchar(45) NOT NULL, 
    `phno` varchar(45) NOT NULL, 
    `nati` varchar(45) NOT NULL, 
    `ppno` varchar(45) NOT NULL, 
    `cuam` varchar(45) NOT NULL, 
    `tcam` varchar(45) NOT NULL, 
    `valu` varchar(45) NOT NULL, 
    `srch` varchar(45) NOT NULL, 
    `stax` varchar(45) NOT NULL, 
    `taxp` varchar(45) NOT NULL, 
    `roun` varchar(45) NOT NULL, 
    `amnt` varchar(45) NOT NULL, 
    `encd` varchar(45) NOT NULL, 
    `mocd` varchar(45) NOT NULL, 
    `endt` varchar(45) NOT NULL, 
    `modt` varchar(45) NOT NULL, 
    `sflg` varchar(5) NOT NULL, 
    `category` varchar(45) NOT NULL DEFAULT 'NA', 
    `branch` varchar(10) NOT NULL, 
    PRIMARY KEY (`numb`,`branch`,`date`) USING BTREE 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=FIXED 
+3

ppno場均指標吧? –

+0

@hexa im不知道....什麼是索引...非常抱歉 – Rajasekar

+0

我的意思是索引 –

回答

3

子查詢是緩慢的。在包含滿足條件的所有ppno的臨時表上使用JOIN。

SELECT T1.* FROM transactions AS T1 
JOIN (SELECT DISTINCT T2.PPNO FROM transactions AS T2 HAVING COUNT(T2.ppno) = $doublescount) AS temp ON temp.PPNO=T1.ppno 
ORDER BY T1.ppno,T1.numb 
+0

對。問題查詢的問題是它依賴於依賴子查詢。這個解決方案將它變成FROM中的一個獨立子查詢,這應該會獲得更好的性能。但是爲了上帝的緣故,請使用有意義的別名而不是T1和T2。呃... – Romain

0

如果瓶頸是數據庫,您也可以省略ORDER BY,並在應用程序而不是數據庫中執行排序。

2

更改SELECT T1.* FROM transactions AS T1,因此它僅提取所需的列,例如SELECT T1.ppno, T1.name FROM transactions as T1,然後使用Gerben的join方法。

當使用SELECT *時,數據庫系統必須計算出數據庫中的哪些列,然後爲每列和每行分配內存 - 在查詢運行之前完成大量後臺工作。 通過使用命名列,數據庫系統只需檢查這些列 - 在運行查詢之前減少後臺工作。

如果您的查詢需要3分鐘執行,您可能會發生笛卡爾連接,結果集可能會遇到數百萬次。戈的加入方法防止此通過使由附加到主表中的子查詢結果的一個臨時表,主查詢運行鍼對該臨時表,以產生一個更小的結果集。兩個表中

+0

他沒有笛卡兒連接,但在這個例子中,在問題的查詢上運行一個'EXPLAIN '將顯示'IN(SELECT ...)'子句產生一個從屬子查詢,意思是子查詢將在外部查詢的結果中每行運行一次,這非常低效。 「加入」解決方案將解決這個問題。 – Romain