現在の実装は、複数の結合と一時テーブルを持つ単一の複雑なクエリですが、MySQL に過度の負荷をかけ、テーブルのロードに 30 秒以上かかっています。データは、JavaScript Ajax 呼び出しを介して PHP によって取得され、Web ページに表示されます。関連するテーブルは次のとおりです。
Table: table_companies
Columns: company_id, ...
Table: table_manufacture_line
Columns: line_id, line_name, ...
Table: table_product_stereo
Columns: product_id, line_id, company_id, assembly_datetime, serial_number, ...
Table: table_product_television
Columns: product_id, line_id, company_id, assembly_datetime, serial_number, warranty_expiry, ...
1 つの会社で、2 つの製品テーブルに分割された 10 万以上のアイテムを持つことができます。製品テーブルは line_name で結合およびフィルター処理され、次に assembly_datetime で並べ替えられ、ページングに応じて制限されます。日時の値もタイムゾーンに依存しており、これはクエリの一部として適用されます (別の JOIN + 一時テーブル)。line_name も返される列の 1 つです。
製品ユニオン クエリから line_name フィルターを分割することを考えていました。基本的に、フィルターに対応する行の ID を特定してから、WHERE 条件を使用して UNION クエリを実行しますWHERE line_id IN (<results from previous query>)
。これにより、結合と一時テーブルの必要性がなくなり、line_name を line_id に適用し、PHP でタイムゾーンを変更できますが、これが最善の方法であるかどうかはわかりません。
Redis を使用する可能性についても調べましたが、多数の個々の製品により、PHP を介してすべてのデータを Redis にプッシュするときに、たとえデータが単に製品テーブル。
- 既存のクエリを微調整して効率を上げることは可能ですか?
- 処理の一部を PHP にプッシュして、SQL サーバーの負荷を軽減できますか? Redisはどうですか?
- テーブルをより適切に設計する方法はありますか?
- 他にどのような解決策を提案しますか?
あなたが提供できる情報に感謝します。
編集:
既存のクエリ:
SELECT line_name,CONVERT_TZ(datetime,'UTC',timezone) datetime,... FROM (SELECT line_name,datetime,... FROM ((SELECT line_id,assembly_datetime datetime,... FROM table_product_stereos WHERE company_id=# ) UNION (SELECT line_id,assembly_datetime datetime,... FROM table_product_televisions WHERE company_id=# )) AS union_products INNER JOIN table_manufacture_line USING (line_id)) AS products INNER JOIN (SELECT timezone FROM table_companies WHERE company_id=# ) AS tz ORDER BY datetime DESC LIMIT 0,100
ここでは、読みやすいようにフォーマットされています。
SELECT line_name,CONVERT_TZ(datetime,'UTC',tz.timezone) datetime,...
FROM (SELECT line_name,datetime,...
FROM (SELECT line_id,assembly_datetime datetime,...
FROM table_product_stereos WHERE company_id=#
UNION
SELECT line_id,assembly_datetime datetime,...
FROM table_product_televisions
WHERE company_id=#
) AS union_products
INNER JOIN table_manufacture_line USING (line_id)
) AS products
INNER JOIN (SELECT timezone
FROM table_companies
WHERE company_id=#
) AS tz
ORDER BY datetime DESC LIMIT 0,100
ID は索引付けされます。主キーは、各列の最初のキーです。