mysql:QUERYごとに順序でインデックスに参加して使用する
-
28-09-2019 - |
質問
StackoverFlowのQ&A機能に似たシステムがあります。主な違いは、各質問に有効期限がある帽子です。
CREATE TABLE questions (
id INT NOT NULL AUTO_INCREMENT,
title CHAR(100) NOT NULL,
details TEXT
PRIMARY KEY (id)
)
CREATE TABLE answers (
id INT NOT NULL AUTO_INCREMENT,
question_id INT NOT NULL
details TEXT
expiration_datetime DATETIME
score INT
PRIMARY KEY (id)
)
スコアによって注文された上位Nの非駆除回答と一緒に質問を表示したいと思います。私はこのようなことを考えています:
SELECT * FROM questions, answers
WHERE questions.id=1 AND questions.id=answers.question_id AND answers.expiration_datetime > NOW()
ORDER BY answers.score DESC LIMIT 10
いくつかの質問:
1)クエリは、私が望むことをするための最も効率的な方法を上回っていますか?次のようなJOINを明示的に使用することとどう違うのですか
SELECT * FROM questions JOIN answers ON questions.id=answers.question_id
WHERE questions.id=1 AND answers.expiration_datetime > NOW()
ORDER BY answers.score DESC LIMIT 10
2)クエリの使用インデックスを作成する方法は?このインデックスをテーブルの回答に追加すると思っています。
INDEX (question_id, expiration_datetime, score)
上記のインデックスは私のクエリのために機能しますか? expiration_datetimeは下降するためにスコアが必要な間、昇順であるため、正しくないようです。ここで何ができますか?
解決
Innine Joinまたはfrom句でテーブルを結合すると、同じ実行計画が与えられます。ただし、前者は読みやすくなります(そして、それが1992年以来標準が示唆していることです)。
RDBMSは、可能な限りインデックスを使用します。通常、実行計画を印刷することをお勧めします(EXPLAIN SELECT * FROM -- ...
)。ただし、複数の列インデックスの作成は難しい場合があることに注意してください。あなたの場合、question_idでインデックスを使用できますが いいえ expiration_datetimeまたはスコアは、インデックスの最初の列ではないためです。 3つの異なるインデックスを作成する必要があります。
ps select *は推奨されていません。必要な列を常に入力し(読みやすく読みやすい)、使用する列のみに言及してください。たとえば、この列をスクリプトで使用しない場合、hirting_dateを選択するポイントはありません!