0

このクエリを単純化する必要があるのは、mysql を保持するサーバーが制限時間内に実行できないためです。

SELECT `B`.*,
       `C`.`name`,
       DATE_ADD(`B`.`SAILING-DATE`, INTERVAL `B`.`NIGHTS` DAY) AS dataEnd 

FROM `table1` AS B 
INNER JOIN `table2` AS A 
INNER JOIN `table3` AS C

WHERE `B`.`ID`=`A`.`ID` 
AND `B`.`CAT`=`A`.`CAT` 
AND `C`.`code`=`A`.`code`
AND (`B`.`NIGHTS`>=$aNumber AND `B`.`NIGHTS`<=$anotherNumber) 
// where are other AND like this on `table1`

約 25.000 行ありますtable1table2

table1すべての結果をループしてすべての結果に対して単一のクエリを作成するよりも、 で最初のクエリを実行するクエリを分割することを考えましたが、効率が悪いと思います。

誰かが私を助けることができますか?ありがとう!!!

編集:

これは説明です:

ここに画像の説明を入力

EDIT2:

I CAN'T ADD INDEX CAUSE THE FIELDIDCATありcode、すべてのテーブルで一意ではありません..それぞれに、同じID CATおよびcode

EDIT3:

すべてをより単純なサブクエリに分割する方が良いと思います..誰かが私にアイデアをくれますか? ありがとう!

4

2 に答える 2

3

あなたが試すことができる1つのことは次のとおりです。

SELECT `B`.*, 
       `C`.`name`, 
       DATE_ADD(`B`.`SAILING-DATE`, INTERVAL `B`.`NIGHTS` DAY) AS dataEnd  

FROM (SELECT * 
         FROM `table1` 
         WHERE table1.NIGHTS >=$aNumber AND table1.NIGHTS <=$anotherNumber) AS B  
INNER JOIN `table2` AS A  ON `B`.`ID`=`A`.`ID` AND `B`.`CAT`=`A`.`CAT`
INNER JOIN `table3` AS C  ON `A`.`code` = `C`.`code`

Nightsこれにより、必要な基準を満たす行のみを選択することで、table1 の行が効果的に事前フィルター処理され、他のテーブルの結合に含まれる数が減ります。

また、JOIN 条件は、ON を使用した INNER JOIN の後にある必要があることに注意してください。このインスタンスでは、実質的に WHERE 句は必要ありません。

調査すべきもう 1 つの点は、クエリ プランです。詳細については、EXPLAINコマンドを参照してください。

この例では、ID、CAT、および CODE 列にインデックスを作成することでメリットが得られる可能性がありますが、単にすべてにインデックスを追加するのではなく、最初に EXPLAIN からの出力を調べて、最適な節約がどこにあるかを確認します。インデックスを追加すると、データを挿入するときのコスト。

編集:

さて、サブクエリはうまく機能しますが、table1 を事前にフィルター処理できない状況が心配です。まず最初に、元のクエリを修正して、それを試してみましょう。

SELECT B.*, 
       C.name, 
       DATE_ADD(B.SAILING-DATE, INTERVAL B.NIGHTS DAY) AS dataEnd  

FROM table1 AS B  
INNER JOIN table2 AS A  ON (B.ID=A.ID AND B.CAT=A.CAT)
INNER JOIN table3 AS C  ON (A.code = C.code)

元のクエリの奇妙な形式 (結合条件は実際に結合しているテーブルに従う必要があります) が何らかの形で MySql を混乱させているのではないかと思います。また、バックティックは不要なので削除しました。私の意見では、クエリが読みにくく (そして入力しにくく) なっています。

パフォーマンスが期待どおりでない場合は、table1 と table2のSHOW INDEXの結果を投稿してください。table1 の ID と CAT および table2 の ID と CAT の組み合わせ (複合インデックス) にインデックスを追加すると、ここでのパフォーマンスが向上する可能性があります。

于 2012-08-07T23:12:00.390 に答える
1

結合に結合条件を入れることから始めて、データベースがクエリを正しく解釈できるようにします。これはおそらくパフォーマンスの違いにはなりませんが、少なくともクエリは人間にとって解釈しやすくなります。

クエリ内のエイリアス名をバッククォートで囲む必要はありません。今はどこにでもあるわけではないので、一貫性を保ち、どこにでも追加するか削除してください。

SELECT B.*,
       C.`name`,
       DATE_ADD(B.`SAILING-DATE`, INTERVAL B.`NIGHTS` DAY) AS dataEnd 

FROM `table1` AS B 
INNER JOIN `table2` AS A ON B.`ID`=A.`ID` AND B.`CAT`=A.`CAT`
INNER JOIN `table3` AS C ON C.`code`=A.`code`
WHERE (B.`NIGHTS`>=$aNumber AND B.`NIGHTS`<=$anotherNumber)

次に、 on など、クエリで使用できるインデックスがあることを確認しますtable2.NIGHTS。このexplainコマンドを使用して、クエリで使用されるインデックスを確認できます。

于 2012-08-07T23:14:34.433 に答える