mysql ビューの使用に大きな問題があります。本当に必要な情報を受け取るためにいくつかのテーブルを結合するビューを生成しています。
私は次の見解を持っています:
CREATE OR REPLACE VIEW view_test AS
SELECT nve_nr.nve_nvenr AS collonr,
CONCAT (adr_emp.adr_name1, "\n", adr_emp.adr_name2, "\n", adr_emp.adr_strasse, "\n", adr_emp.adr_land , " - ", adr_emp.adr_plz, " ", adr_emp.adr_ort) AS emp_adr,
UNIX_TIMESTAMP((SELECT MAX(t_1.colst_timestamp) FROM tbl_collo_status t_1 WHERE t_1.colst_nve_id =
nve_nr.nve_id AND t_1.colst_status_code IN (10, 11, 76))) AS status_x,
UNIX_TIMESTAMP((SELECT MAX(t_2.colst_timestamp) FROM tbl_collo_status t_2 WHERE t_2.colst_nve_id =
nve_nr.nve_id AND t_2.colst_status_code IN (20,25,91))) AS status_y,
UNIX_TIMESTAMP((SELECT MAX(t_3.colst_timestamp) FROM tbl_collo_status t_3 WHERE t_3.colst_nve_id =
nve_nr.nve_id AND t_3.colst_status_code IN (30,99,104))) AS status_z,
TIME_TO_SEC(TIMEDIFF((SELECT MAX(t_2.colst_timestamp) FROM tbl_collo_status t_2 WHERE t_2.colst_nve_id =
nve_nr.nve_id AND t_2.colst_status_code IN (20,25,91)), (SELECT MAX(t_1.colst_timestamp) FROM tbl_collo_status t_1
WHERE t_1.colst_nve_id = nve_nr.nve_id AND t_1.colst_status_code IN (10, 11, 76)))) AS timediff_xy,
TIME_TO_SEC(TIMEDIFF((SELECT MAX(t_3.colst_timestamp) FROM tbl_collo_status t_3 WHERE t_3.colst_nve_id =
nve_nr.nve_id AND t_3.colst_status_code IN (30,99,104)), (SELECT MAX(t_2.colst_timestamp) FROM tbl_collo_status t_2
WHERE t_2.colst_nve_id = nve_nr.nve_id AND t_2.colst_status_code IN (20,25,91)))) AS timediff_yz,
TIME_TO_SEC(TIMEDIFF((SELECT MAX(t_3.colst_timestamp) FROM tbl_collo_status t_3 WHERE t_3.colst_nve_id =
nve_nr.nve_id AND t_3.colst_status_code IN (30,99,104)), (SELECT MAX(t_1.colst_timestamp) FROM tbl_collo_status t_1
WHERE t_1.colst_nve_id = nve_nr.nve_id AND t_1.colst_status_code IN (10, 11, 76)))) AS timediff_xz,
CAST(SUBSTR(nve_nr.nve_nvenr, 1, 3) AS UNSIGNED INTEGER) AS filter_collonr,
(SELECT t_5.colst_status_code FROM tbl_collo_status t_5 WHERE t_5.colst_nve_id=nve_nr.nve_id ORDER BY
t_5.colst_timestamp DESC LIMIT 1) AS filter_last_status,
sdg.sdg_kunde AS filter_kunden_id,
sdg.sdg_id AS filter_sdg_id,
nve_nr.nve_id AS filter_nve_id,
adr_emp.adr_id AS filter_adr_emp_id
FROM ((tbl_nve_nr nve_nr LEFT JOIN tbl_sendungen sdg ON nve_nr.nve_sdg_id = sdg.sdg_id)
LEFT JOIN tbl_adressen adr_emp ON adr_emp.adr_id = sdg.sdg_adr2_id);
現在、そのビューには 250.000 を超えるデータセットがあり、そのビューで選択を開始すると、結果を受け取るまでに 20 分以上かかります。Explain Select は以下を返します。
//![ビューからの選択の説明][1]
評判が10にならないと画像を投稿できないので、次のようにしてみます。
ビューを高速化するために何ができるか教えてもらえますか? ビューを使用せずにクエリを実行すると、250.000 の利用可能なデータセットから選択する必要がある 25 のデータセットの制限で約 2 分かかります。
//編集:だから私は別の方法で問題を解決しました:)以下に説明する解決策は、SQLクエリが十分に速く動作しないため、次の方法で解決しました:
ビューが不要になったため、ビューを削除します。テーブル nve_nr を変更して、最後のステータスとそのタイムスタンプ用の 2 つのフィールドを追加します。タイムスタンプが既存のものよりも新しい場合、その値を置き換える collo_status でトリガーを作成します。-> したがって、サブクエリが 1 つ少なくなります - 2 分から 60 秒近くにスピードアップします。
インデックスを再構築し、php で直接クエリを実行します -> php のコードが増えますが、はるかに太くなります - 今では 13 秒近くまで高速化されています :)
新しいフィールドでデータベースを更新するには、現在の最新のステータスを見つける手順が含まれます。
したがって、新しいクエリは次のようになります。
SELECT SQL_CALC_FOUND_ROWS
sdg.sdg_lieferschein AS referenz,
nve_nr.nve_nvenr AS collonr,
nve_nr.nve_last_timestamp AS filter_status_time,
nve_nr.nve_last_status AS filter_last_status,
sdg.sdg_kunde AS filter_kunden_id,
sdg.sdg_id AS filter_sdg_id,
nve_nr.nve_id AS filter_nve_id,
adr_emp.adr_id AS filter_adr_emp_id,
adr_emp.adr_name1 AS emp_adr_name1,
adr_emp.adr_name2 AS emp_adr_name2,
adr_emp.adr_land AS emp_adr_land,
adr_emp.adr_plz AS emp_adr_plz,
adr_emp.adr_ort AS emp_adr_ort,
UNIX_TIMESTAMP(t_1.colst_timestamp) AS status_x,
t_1.colst_status_code AS status_code_x,
UNIX_TIMESTAMP(t_2.colst_timestamp) AS status_y,
t_2.colst_status_code AS status_code_y,
UNIX_TIMESTAMP(t_3.colst_timestamp) AS status_z,
t_3.colst_status_code AS status_code_z,
TIME_TO_SEC(TIMEDIFF(t_2.colst_timestamp, t_1.colst_timestamp)) AS timediff_xy,
TIME_TO_SEC(TIMEDIFF(t_3.colst_timestamp, t_2.colst_timestamp)) AS timediff_yz,
TIME_TO_SEC(TIMEDIFF(t_3.colst_timestamp, t_1.colst_timestamp)) AS timediff_xz,
CAST(SUBSTR(nve_nr.nve_nvenr, 1, 3) AS UNSIGNED INTEGER) AS filter_collonr
FROM tbl_nve_nr nve_nr
LEFT JOIN tbl_sendungen sdg
ON nve_nr.nve_sdg_id = sdg.sdg_id
LEFT JOIN tbl_adressen adr_emp
ON (adr_emp.adr_id = sdg.sdg_adr2_id)
LEFT JOIN tbl_collo_status t_1
ON (t_1.colst_nve_id = nve_nr.nve_id AND t_1.colst_aktiv = 1 AND t_1.colst_status_code IN (10, 11, 76))
LEFT JOIN tbl_collo_status t_2
ON (t_2.colst_nve_id = nve_nr.nve_id AND t_2.colst_aktiv = 1 AND t_2.colst_status_code IN (20,25,91))
LEFT JOIN tbl_collo_status t_3
ON (t_3.colst_nve_id = nve_nr.nve_id AND t_3.colst_aktiv = 1 AND t_3.colst_status_code IN (30,99,104))
GROUP BY collonr
ORDER BY collonr DESC
LIMIT 900, 75