0

別のテーブルの別のフィールドに一致するフィールド情報を解析する必要があるこのクエリを実行する必要があります。次に、いくつかのテーブルでリンスして繰り返すと、最終的に目的の行が返されます。

問題は、どうすればこれを高速化できるかということです...数十万行が返され、クエリがクラッシュを引き起こしているため、クライアントの管理セクションでうまく機能していません。

クエリは次のとおりです。

SELECT DISTINCT t1.CU_ship_name1, t1.CU_ship_name2, t1.CU_email 
FROM (
      SELECT CU_id, CU_ship_name1, CU_ship_name2, CU_email
      FROM customers 
      WHERE CU_solicit=1 
      AND CU_cdate >=".$startDate." 
      AND CU_cdate <=".$endDate."
     )AS t1
INNER JOIN orders AS t2 ON t1.CU_id = t2.O_cid 
INNER JOIN item AS t3 ON t2.O_ref = t3.I_oref 
INNER JOIN product AS t4 ON t3.I_pid = t4.P_id 
INNER JOIN (
            SELECT C_id FROM category WHERE C_store_type =1
           ) AS t5 ON t4.P_cat = t5.C_id

「customers」、「orders」、「item」テーブルは毎月数万の新しい行で更新され、「product」テーブルは毎月少なくとも 100 行の新しい行を受け取ります。

私が考えられる唯一のことは、この情報を保持する新しいテーブルを作成し (これは理想的な解決策ではありません)、これらのテーブルにインデックスを追加することでした。これらのテーブルは非常に多くの新しいデータを取得するため、インデックスを恐れていますが、試してみるつもりです (いつでも元に戻すことができますか?)。しかし、インデックス自体が問題を解決するとは思えません。

更新:私は現在、このクエリを使用しており、より高速な結果を取得しています。すべての WHERE および JOIN ON 行のインデックスを作成しても、まったく役に立ちませんでした...理由がわかりません。

サブクエリの削除:

以下のクエリで 3 ~ 4 秒から、同じ permeters で 151 秒まで、クエリの速度に悲惨な影響を与えました。

SELECT DISTINCT t1.CU_ship_name1, t1.CU_ship_name2, t1.CU_email 
FROM customers AS t1 
WHERE t1.CU_solicit=1 
AND t1.CU_cdate>= 20100725000000
AND t1.CU_cdate<= 20100801000000
AND EXISTS(
    SELECT NULL FROM orders AS t2
    INNER JOIN item AS t3 ON t2.O_ref = t3.I_oref 
    INNER JOIN product AS t4 ON t3.I_pid = t4.P_id 
    INNER JOIN (
        SELECT C_id 
        FROM category 
        WHERE C_store_type = 2
    ) AS t5 ON t4.P_cat = t5.C_id
    WHERE t1.CU_id = t2.O_cid);

気にしないでください、私はそれらを通常の結合とサブクエリなしに変更しました。クエリは次のとおりです。

SELECT DISTINCT t1.CU_ship_name1, t1.CU_ship_name2, t1.CU_email 
FROM customers AS t1 
JOIN orders AS t2 ON t1.CU_id = t2.O_cid 
JOIN item AS t3 ON t2.O_ref = t3.I_oref 
JOIN product AS t4 ON t3.I_pid = t4.P_id 
JOIN category AS t5 ON t4.P_cat = t5.C_id 
WHERE t1.CU_solicit =1 
AND t1.CU_cdate >=20100425000000
AND t1.CU_cdate <=20100801000000
AND t5.C_store_type =2
4

2 に答える 2

2

私は2つのことを試してみます:

1) ON 句と WHERE 句で使用する列にインデックスを追加します

2) 通常の JOIN および WHERE 条件としてサブクエリを書き換えて、サブクエリを削除します。

これらを実行してもまだ問題があることがわかった場合にのみ、他のオプションを検討する必要があります。

これは、不要なサブクエリを除けば、非常に単純なクエリのように見えます。インデックスが定義されていないか、MySQL で使用できるメモリが少なすぎるか、使用可能なリソースに対して MySQL サーバー自体を非常に貧弱に構成していない限り、何百万行でも遅くなるとは思わないでしょう。

1 か月に 1 万行の新しい行は、何もありません。数分ごとに新しい行を入れています。どのインデックスを定義するかを決定する際には、それは考慮に値しません。安価なサーバー上の MySQL は、1 秒間に数百回の挿入を処理できます。

于 2010-11-18T23:45:53.670 に答える
1

where Criteria と ON ステートメントの列にインデックスを付けます。インデックスはクラッシュの問題にすぐに対処し、おそらく変更操作を大幅に低下させません。DBが弱いマシン上にない限り、毎月何万行も実際にはそれほど多くの行ではありません。

さらに、サブクエリを完全に削除することを検討します。多くの場合、SQL サーバーのパフォーマンスが低下します。サーバーが実行計画をキャッシュできるように、クエリをストアド プロシージャに移動することも検討してください。

于 2010-11-18T23:47:15.790 に答える