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

多くの行をスキャンしないようにMySQLクエリを最適化する

    クエリが多数の行を検査すると思われる理由は何ですか?

    クエリは正確に30をスキャンします UNIQUEを使用して記録する tag (tag, article_id)のインデックス 、PRIMARY KEYの各レコードに記事を結合します 停止します。

    これはまさにあなたの計画が言っていることです。

    このテストスクリプトを作成しました:

    CREATE TABLE `article` (
      `id` int(11) NOT NULL auto_increment,
      `title` varchar(60) NOT NULL,
      `time_stamp` int(11) NOT NULL,
      PRIMARY KEY  (`id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1000001 ;
    
    CREATE TABLE `tag` (
      `tag` varchar(30) NOT NULL,
      `article_id` int(11) NOT NULL,
      UNIQUE KEY `tag` (`tag`,`article_id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
    
    INSERT
    INTO    article
    SELECT  id, CONCAT('Article ', id), UNIX_TIMESTAMP('2011-08-17' - INTERVAL id SECOND)
    FROM    t_source;
    
    INSERT
    INTO    tag
    SELECT  CASE fld WHEN 1 THEN CONCAT('tag', (id - 1) div 10 + 1) ELSE tag END AS tag, id
    FROM    (
            SELECT  tag,
                    id,
                    FIELD(tag, 'Other', 'Acer', 'Sony', 'HP', 'Dell') AS fld,
                    RAND(20110817) AS rnd
            FROM    (
                    SELECT  'Other' AS tag
                    UNION ALL
                    SELECT  'Acer' AS tag
                    UNION ALL
                    SELECT  'Sony' AS tag
                    UNION ALL
                    SELECT  'HP' AS tag
                    UNION ALL
                    SELECT  'Dell' AS tag
                    ) t
            JOIN    t_source
            ) q
    WHERE   POWER(3, -fld) > rnd;
    

    、ここでt_source 1Mのテーブルです その中に記録し、クエリを実行します:

    SELECT  *
    FROM    tag t
    JOIN    article a
    ON      a.id = t.article_id
    WHERE   t.tag = 'acer'
    ORDER BY
            t.article_id DESC
    LIMIT 30;
    

    あっという間でした。



    1. 条件付きSQLクエリ支援

    2. 'IS DISTINCT FROM'は本当のMySQLオペレーターですか?

    3. VARCHARフィールドでの文字列の出現回数をカウントしますか?

    4. ホットスタンバイ展開のトレードオフ