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

条件を追加した後の深刻なMySQLクエリのパフォーマンスの問題

    SHOW CREATE TABLEを入力してください 。

    これらの複合インデックスを見たいと思います:

    `val`: (entityId, attributeId)   -- order is not critical
    

    残念ながら、code LONGTEXTです 、これはentityでは不可能です :INDEX(type, code, entityId) 。したがって、これはあまり効率的ではありません:

            SELECT  entityId
                from  entity
                where  code = v9.Value
                  and  type = 97
                limit  1
    

    LIMITが表示されます ORDER BYを使用 -どの値を取得するか気になりますか?

    おそらくそれは次のように書くほうがよいでしょう

        WHERE EXISTS ( SELECT 1 FROM entity
                    WHERE entityID = e3.entityID
                      AND code     = v9.Value
                      AND type = 97 )
    

    e3の混合についてはよろしいですか およびv9 ?)

    ラッピング...

    これにより、LEFT JOINが強制されます JOINになる 。そしてそれはその時内側のORDER BYを取り除きます 。

    次に、オプティマイザーはおそらく68e9145e-43eb-4581-9727-4212be41bef5から始めるのが最善であると判断します。 、私はこれをval AS v11と呼んでいます :

    JOIN val AS v11 ON (v11.entityId = e2.id
                 and  v11.attributeId = 1614)
                 AND  v11.Value = 'bar2')
    

    これがEAVテーブルの場合、[、1514]の値が「bar2」であることを確認するだけです。これは賢明なテストのようには思えません。

    以前の推奨事項に加えて。

    EXPLAIN SELECT ...がいいです 。

    EAV

    valを想定 は従来のEAVテーブルですが、これはおそらくはるかに優れています:

    CREATE TABLE `val` (
      `attributeId` int(11) NOT NULL,
      `entityId` int(11) NOT NULL,
      `Value` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
      PRIMARY KEY(`entityId`,`attributeId`),
      KEY `IX_val_attributeId` (`attributeId`),
    ) ENGINE=InnoDB AUTO_INCREMENT=2325375 DEFAULT CHARSET=latin1
    

    2つのIDは実用的ではありません(何かが足りない場合を除く)。フレームワークのためにそれらを使用することを余儀なくされた場合、それは残念です。 (entityId、attributeId)をPKにプロモートすると、valueがフェッチされます。 少し速くなります。

    LONGTEXTを含める便利な方法はありません どのインデックスでも、以前の提案のいくつかを変更する必要があります。




    1. MSSQLサーバーでPDOを使用しているときにドライバーエラーを見つけることができませんでした

    2. mysqlエラーメッセージを接続できないことを理解する方法は?

    3. テーブルを更新するときに読み取りを防止する

    4. SQL ServerManagementStudioでSQLをフォーマットする