この低パフォーマンスMySQLクエリを最適化する方法は?
-
01-10-2019 - |
質問
現在、JSPerfの次のクエリを使用しています。おそらくあなたはJSperfを知らない場合 - 2つのテーブルがあります: pages
テストケース /リビジョンを含む tests
テストケース内のテスト用のコードスニペットを含む。
現在、937のレコードがあります pages
および3817のレコード tests
.
ご覧のとおり、ロードにはかなり時間がかかります 「browse jsperf」ページ このクエリが使用される場所。
クエリの実行には約7秒かかります。
SELECT
id AS pID,
slug AS url,
revision,
title,
published,
updated,
(
SELECT COUNT(*)
FROM pages
WHERE slug = url
AND visible = "y"
) AS revisionCount,
(
SELECT COUNT(*)
FROM tests
WHERE pageID = pID
) AS testCount
FROM pages
WHERE updated IN (
SELECT MAX(updated)
FROM pages
WHERE visible = "y"
GROUP BY slug
)
AND visible = "y"
ORDER BY updated DESC
表示されるすべてのフィールドにインデックスを追加しました WHERE
条項。さらに追加する必要がありますか?
このクエリを最適化するにはどうすればよいですか?
PS私はPHPでキャッシュシステムを実装できることを知っています - 私はおそらく私に言わないでください:)私は本当にこのクエリをどのように改善できるかを知りたいだけです。
解決
使用する:
SELECT x.id AS pID,
x.slug AS url,
x.revision,
x.title,
x.published,
x.updated,
y.revisionCount,
COALESCE(z.testCount, 0) AS testCount
FROM pages x
JOIN (SELECT p.slug,
MAX(p.updated) AS max_updated,
COUNT(*) AS revisionCount
FROM pages p
WHERE p.visible = 'y'
GROUP BY p.slug) y ON y.slug = x.slug
AND y.max_updated = x.updated
LEFT JOIN (SELECT t.pageid,
COUNT(*) AS testCount
FROM tests t
GROUP BY t.pageid) z ON z.pageid = x.id
ORDER BY updated DESC
他のヒント
説明の使用方法を学びたいです。これにより、SQLステートメントが実行され、どのインデックスが使用されているか、どの行スキャンが実行されているかが表示されます。目標は、行スキャンの数を減らすことです(つまり、データベースは行を列ごとに検索します)。
サブQueriesを一度に1つずつ試して、どれが最も遅いかを確認することをお勧めします。
このクエリ:
SELECT MAX(updated)
FROM pages
WHERE visible = "y"
GROUP BY slug
結果をスラッグで並べ替えます。これはおそらく遅いです。
所属していません StackOverflow