25

MySQL 以外ではかなり単純に感じます。

基本的に、特定の用語が返す結果の数に基づいて、他のいくつかの条件とともに、使用しているインデックスの種類を切り替える必要があります。

効果のあるもの:

IF (SELECT COUNT(*) FROM table WHERE term LIKE "term") > 4000
   EXECUTE QUERY A
ELSE
   EXECUTE QUERY B

これは MySQL ステートメントで可能ですか?

編集:

クエリ A:

SELECT id 
FROM table_a
FORCE INDEX(id)
JOIN table_b ON table_a.id = table_b.id
WHERE term LIKE "term"
ORDER BY date
LIMIT 100;

クエリ B:

SELECT id 
FROM table_a
FORCE INDEX(term)
JOIN table_b ON table_a.id = table_b.id
WHERE term LIKE "term"
GROUP BY term    # These lines would be included for a few conditions not mentioned above.. but are necessary
HAVING COUNT = 1 # same...  
ORDER BY date
LIMIT 100;

クエリを切り替える理由は、「用語」の人気度に基づいて結果時間が劇的に異なるためです。

4

2 に答える 2

23

編集:ストアド プロシージャの必要性について以下で述べたことは真実ではありません。これを試して:

SELECT CASE WHEN ( (SELECT COUNT(*) FROM table WHERE term LIKE "term") > 4000 )
    THEN <QUERY A>
    ELSE <QUERY B>
END

これは確かにケース式であり、ストアド プロシージャの外でも問題なく動作します :-)

例えば:

mysql> SELECT CASE WHEN ( 5 > 4 ) THEN ( SELECT 'foo' ) ELSE ( SELECT 'bar' ) END;
+---------------------------------------------------------------------+
| CASE WHEN ( 5 > 4 ) THEN ( SELECT 'foo' ) ELSE ( SELECT 'bar' ) END |
+---------------------------------------------------------------------+
| foo                                                                 |
+---------------------------------------------------------------------+
1 row in set (0.01 sec)

mysql> SELECT CASE WHEN ( 3 > 4 ) THEN ( SELECT 'foo' ) ELSE ( SELECT 'bar' ) END;
+---------------------------------------------------------------------+
| CASE WHEN ( 3 > 4 ) THEN ( SELECT 'foo' ) ELSE ( SELECT 'bar' ) END |
+---------------------------------------------------------------------+
| bar                                                                 |
+---------------------------------------------------------------------+
1 row in set (0.00 sec)

すでに賛成票を集めているため、歴史的な関心に対する以下の古い回答:

以下を使用できると思いますが、ストアドプロシージャ内でのみ使用できます。

CASE (SELECT COUNT(*) FROM table WHERE term LIKE "term") > 4000
    WHEN 1 THEN <QUERY A>
    ELSE <QUERY B>
END CASE

これは、式CASEとは異なるステートメントCASEです... https://dev.mysql.com/doc/refman/5.0/en/case.htmlには、さらに悲惨な詳細があります。

実際、条件付きでさまざまなクエリを実行したい場合は、一般的に、ストアド プロシージャに目を向ける必要があるのではないかと思います。間違っている可能性もありますが、現時点ではそれが私の直感です。できるとしたらCASE式でしょう!

最後の編集: 実際の例では、アプリケーションで条件付きビットを実行し、何を検索するかを決定したら、SQL (または SQL を生成する ORM) に渡すだけです。

于 2013-06-19T20:40:24.827 に答える
4

試す:

select coalesce(i.id, t.id) id
from (SELECT COUNT(*) countterm FROM table WHERE term LIKE "term") c
left join
     (SELECT id, date
      FROM table_a
      FORCE INDEX(id)
      JOIN table_b ON table_a.id = table_b.id
      WHERE term LIKE "term") i on countterm > 4000
left join
     (SELECT id, date
      FROM table_a
      FORCE INDEX(term)
      JOIN table_b ON table_a.id = table_b.id
      WHERE term LIKE "term"
      GROUP BY term
      HAVING COUNT = 1) t on countterm <= 4000
ORDER BY coalesce(i.date, t.date)
LIMIT 100;
于 2013-06-19T19:49:49.073 に答える