sql >> データベース >  >> RDS >> Mysql

MySQL:複合インデックスフルテキスト+ btree?

    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(...)
    

    この定式化と索引付けは次のように機能するはずです:

    1. FULLTEXTを使用する 30K行を見つけるには、PKを配信します。
    2. PKを使用して、30K行をdateで並べ替えます 。
    3. 最後の10個を選択して、date, idを配信します
    4. PKを使用してテーブルに10回戻ります。
    5. もう一度並べ替えます。 (ええ、これは必要です。)

    もっと (多数のコメントへの対応):

    私の改革の背後にある目標は、すべてを取得しないようにすることです。 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の経験がないので、その質問に答えることはできません。)




    1. SQLDeveloperアイコン

    2. 単一のスペースを文字列で比較する方法

    3. SQLite Select Distinct

    4. ストアドプロシージャを実行する場合、CommandType.Textを使用するのと比較してCommandType.StoredProcedureを使用する利点は何ですか?