0

SELECTクエリで「不可能なWHERE」が発生しているようです。以下に2つのクエリを投稿しました。これらは、サブクエリで区別されます。これらのクエリは、カウントを更新する前に、ユーザーが以前に何かを保存したことがあるかどうかを確認します。テスト目的でSELECTを使用していますが、実際のクエリはUPDATEを使用しています。

UPDATE articles SET article_count = article_count+1 
WHERE id = 2343243 AND (
    SELECT COUNT(*) 
    FROM posts as p
    WHERE p.post_id = 2343243 AND p.user_id = 3
) = 1;

次の2つのクエリは、データがテーブルにあるかどうかを確認するためにテストに使用しているものです(テストのみ)。

EXPLAIN 
SELECT a.id 
FROM articles as a 
WHERE a.id = 2343243 AND (
    SELECT COUNT(*) 
    FROM posts as p
    WHERE p.post_id = a.id AND p.user_id = 3
) = 1;

クエリ1Impossible WHEREはEXPLAINで返されます。クエリ#2のselect_typeはSUBQUERYです。

EXPLAIN 
SELECT a.id 
FROM articles as a 
WHERE a.id = 2343243 AND (
    SELECT COUNT(*) 
    FROM posts as p
    WHERE p.post_id = 2343243 AND p.user_id = 3
) = 1;

クエリ2Impossible WHERE noticed after reading const tablesはEXPLAINで返されます。クエリ2のselect_typeはDEPENDENTSUBQUERYです。

質問:これを不可能ではないWHEREクエリにする方法についてのアイデアはありますか?また、どちらが速いでしょうか?

4

2 に答える 2

1

Impossible WHERE について Mysql.com で読んだ後、クエリで WHERE 1 = 1 のような制約を使用することは実際には良い考えではありません。

この条件が真になることは決してないため、EXPLAIN ステートメントには Impossible WHERE という単語が表示されます。非公式に言えば、MySQL では WHERE が最適化されていないと言っています。

Mysql.com: http://dev.mysql.com/doc/internals/en/optimizer-eliminating-dead-code.html

メインクエリとサブクエリの両方にインデックスを使用する新しいクエリを作成するために、そのクエリを捨てることにしました。これは、より高速なソリューションであり、一見複雑ではありません。

UPDATE articles 
SET article_count = IF (
    (SELECT count(*) FROM posts WHERE post_id = 2343243 AND user_id = 3) = 1, article_count+1, article_count) 
WHERE id = 2343243;
于 2012-08-17T04:00:37.177 に答える
0

実際の定数を使用しない準備済みステートメントが役立つ場合があります (mysql が、データに基づいて不可能を宣言するためにテストしている実際の定数を使用している場合)

于 2012-08-17T03:08:16.410 に答える