0

顧客が製品ページをロードすると、製品に関する質問が表示されるように、質問/回答テーブルをセットアップしています。同じ質問が何度も表示されないようにするために、回答テーブルを質問テーブルに結合し、その製品についてそのユーザーがまだ回答していない最初の 3 つの質問を選択するクエリがあります。

CREATE TABLE `questions` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `question` varchar(100) NOT NULL,
    PRIMARY KEY (`id`),
    UNIQUE KEY `idquestion` (`id`,`question`)
) ENGINE=InnoDB AUTO_INCREMENT=37 DEFAULT CHARSET=utf8


CREATE TABLE `answers` (
    `questionId` int(11) NOT NULL,
    `userId` int(11) NOT NULL,
    `productId` int(11) NOT NULL,
    `answer` tinyint(3) unsigned NOT NULL DEFAULT ''0'',
    PRIMARY KEY (`questionId`,`userId`,`productId`),
    KEY `questionId` (`questionId`),
    KEY `userId` (`userId`),
    KEY `productId` (`productId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

私が使用しているクエリは次のとおりです。

SELECT q.`id`, q.`question`
FROM `questions` q
LEFT JOIN `answers` a
ON q.`id` = a.`questionId` AND a.`userId` = <userid> AND da.`productId` = <productid>
WHERE a.`productId` IS NULL
LIMIT 3;

EXPLAIN EXTENDED結果は次のとおりです。

1   SIMPLE  q   index       idquestion  306     34  100.00  Using index
1   SIMPLE  a   eq_ref  questionIduserIdproductId,questionId,userId,productId   questionIduserIdproductId   12  sandbox.q.id,const,const    1   100.00  Using where; Using index; Not exists

クエリは、まだ回答されていない適切な質問を返す際にうまく機能します。問題は、このクエリが負荷の下でラグアウトし、両方の行がインデックスを使用していることを示していても、このクエリをlog-queries-not-using-indexes有効にすると、まだ slow-query.log に表示されることです。なぜこれが起こっているのか誰かが私に説明できますか? 別のインデックスが必要ですか?UNIQUEキーへの回答のために既存のPRIMARYキーを変更して追加しようとしました

`id` int(10) unsigned NOT NULL AUTO_INCREMENT

PRIMARYキーとしてですが、それは何もしませんでした。

どんな助けでも大歓迎です。

ありがとう!

4

1 に答える 1

0

productId が回答テーブルではなく、質問テーブルの一部ではない理由について混乱しています。このクエリは、製品の最初の 3 つの未回答の質問を返すように見えます...

クエリが遅いのは、LEFT JOIN が原因です。questionsに一致する行がないからすべての行を返していanswersます。これは idquestion インデックスを使用して実行できますが (必要な列が両方ともインデックスにあるため)、毎回 Answers テーブルをプローブする必要があります。

于 2013-04-27T00:13:22.810 に答える