2011-06-19 10 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分かかります....このクエリを高速化する方法。

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イムわからない....指標...私はインデックスを意味 – Rajasekar

+0

非常に残念 –

答えて

3

サブクエリが遅いNULLに登録しよう:Plzを

EDIT 1は助けます。条件を満たすすべての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を省略して、DBではなくアプリケーションで並べ替えることもできます。

2

SELECT T1.* FROM transactions AS T1を変更して、必要な列(たとえば、SELECT T1.ppno, T1.name FROM transactions as T1)だけをフェッチしてから、Gerbenの参加メソッドを使用してください。

SELECT *が使用されている場合、データベースシステムはデータベース内のどの列を処理してから、各列と行にメモリを割り当てる必要があります。 名前付き列を使用すると、データベースシステムは列をチェックするだけで済みます。

クエリを実行するために3minsを取っている場合、あなたはおそらくデカルトは、結果セットが潜在的に何百万人に遭遇する可能性があり、起こって参加しています。 gerbenのjoinメソッドは、サブテーブルの結果をメインテーブルに追加したテンポラリテーブルを作成することでこれを防ぎます。メインクエリはこのテンポラリテーブルに対して実行され、より小さな結果セットが生成されます。両方のテーブルの

+0

を彼が参加するが、この例では、 '' INは依存サブクエリで '節の結果(SELECT ...)をすることを示すであろう問題のクエリに' をEXPLAIN実行しているデカルトを持っていない、の意味副問合せは外部問合せの結果で行ごとに1回実行されますが、これは非常に非効率的です。 'Join'の解決策がこれを修正します。 – Romain

関連する問題