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

このmysqlクエリ(nullチェックあり)が他のクエリよりも遅いのはなぜですか?

    どちらかが速いことに驚いています。それらをexistsに置き換えることをお勧めします :

    SELECT COUNT(*)
    FROM ips_usuario u  
    WHERE EXISTS (SELECT 1 FROM ips_fatura f WHERE u.id = f.ips_usuario_id) OR
          EXISTS (SELECT 1 FROM ips_fatura f WHERE u.ips_usuario_id_titular = f.ips_usuario_id);
    

    そして2番目に:

    SELECT COUNT(*)
    FROM ips_usuario u  
    WHERE EXISTS (SELECT 1 FROM ips_fatura f WHERE u.id = f.ips_usuario_id) OR
          (u.ips_usuario_id_titular IS NOT NULL AND
           EXISTS (SELECT 1 FROM ips_fatura f WHERE u.ips_usuario_id_titular = f.ips_usuario_id)
          )
    

    これらの両方に対して、2つのインデックスが必要です:ips_fatura(ips_usuario_id) およびips_fatura(ips_usuario_id_titular) 。説明をチェックして、EXISTSであることを確認できます インデックスを使用しています。そうでない場合、MySQLの新しいリリースはINのインデックスを使用します :

    SELECT COUNT(*)
    FROM ips_usuario u  
    WHERE u.id IN (SELECT f.ips_usuario_id FROM ips_fatura f) OR
          u.ips_usuario_id_titular IN (SELECT f.ips_usuario_id FROM ips_fatura f);
    

    いずれの場合も(EXISTS またはIN )目標は「半結合」を行うことです。つまり、すべての一致ではなく、一致する最初の行のみを細かく設定します。これにより、クエリで重複の削除を回避できるため、これは重要な効率です。

    問題はorの最適化だと思います -通常、これは非効率的なJOINになります アルゴリズム。ただし、最初のケースでは、MySQLが賢いのかもしれません。ただし、IS NULLの追加 外側のテーブルにそれを捨てます。




    1. MYSQLとLIMIT句

    2. SQL Serverのvarchar列から奇妙な文字(帽子をかぶったA)を削除します

    3. PharoSmalltalkとmySql

    4. 大きなテキスト/CSVファイルをPLSQLで複数のファイルに分割