IN BOOLEAN MODE
を使用する 。
日付インデックスは役に立ちません。 2つのインデックスを組み合わせる方法はありません。
ユーザーが30K行に表示されるものを検索すると、クエリが遅くなることに注意してください。その周りに簡単なことはありません。
TEXT
があると思います テーブルの列?もしそうなら、希望があります。やみくもにSELECT *
を実行する代わりに 、最初にIDを見つけて、LIMIT
を取得しましょう 適用、その後 *
を実行します 。
SELECT a.*
FROM tbl AS a
JOIN ( SELECT date, id
FROM tbl
WHERE MATCH(...) AGAINST (...)
ORDER BY date DESC
LIMIT 10 ) AS x
USING(date, id)
ORDER BY date DESC;
一緒に
PRIMARY KEY(date, id),
INDEX(id),
FULLTEXT(...)
この定式化と索引付けは次のように機能するはずです:
-
FULLTEXT
を使用する 30K行を見つけるには、PKを配信します。 - PKを使用して、30K行を
date
で並べ替えます 。 - 最後の10個を選択して、
date, id
を配信します - PKを使用してテーブルに10回戻ります。
- もう一度並べ替えます。 (ええ、これは必要です。)
もっと (多数のコメントへの対応):
私の改革の背後にある目標は、すべてを取得しないようにすることです。 30Kの列 行。代わりに、PRIMARY KEY
のみをフェッチします 、次にそれを10に減らし、*
をフェッチします たった10行。押しつぶされるものははるかに少ない。
COUNT
について InnoDBテーブル:
- INDEX(col)を使用すると、 index スキャンは
SELECT COUNT(*)
で機能します またはSELECT COUNT(col)
WHERE
なし 。 -
INDEX(col),
SELECT COUNT(*)will use the "smallest" index; but
SELECT COUNT(col)`にはテーブルが必要です スキャンします。 - テーブルスキャンは通常です インデックススキャンよりも遅い。
- タイミングに注意してください-インデックスやテーブルがすでにRAMにキャッシュされているかどうかによって大きく影響されます。
FULLTEXT
についてのもう1つのこと +
です 単語の前に-各単語が存在しなければならないと言うこと、そうでなければ一致はありません。これにより、30Kが削減される可能性があります。
FULLTEXT
インデックスはdate, id
を配信します ランダムな順序であり、PKの順序ではありません。とにかく、順序を想定するのは「間違っている」ので、ORDER BY
を追加するのは「正しい」です。 、次にオプティマイザーに知っている場合はそれを投げさせます 冗長であること。また、オプティマイザーがORDER BY
を利用できる場合もあります。 (あなたの場合ではありません)。
ORDER BY
だけを削除する 、多くの場合、クエリの実行がはるかに高速になります。これは、たとえば30K行のフェッチと並べ替えを回避するためです。代わりに、単に「任意の」10行を配信します。
(私はPostgresの経験がないので、その質問に答えることはできません。)