2017-03-21 11 views
0

バトルフィールドゲームの統計レポートサイトでクエリのパフォーマンスを向上させようとしており、非常に特定のクエリで少し問題があります。私が抱えている問題は、EXPLAINがこのクエリがフルテーブルスキャンを行っているということです。これは、このテーブルが非常に大きくなる(100万行以上の可能性がある)ので、面倒です。私は選択したデータベースとしてMySQL 5.7を使用しています。ここでJoin、フルテーブルスキャンによるクエリパフォーマンスの向上

は私のテーブルやクエリです: enter image description here

私は以来、あなたの一つは、私はこのクエリのパフォーマンスを向上させることができることを期待しています:ここでhttp://pastebin.com/DsiGe2UB

-- 
    -- Table structure for table `player_kit` 
    -- 

    CREATE TABLE `player_kit` (
     `id` TINYINT UNSIGNED NOT NULL, 
     `pid` INT UNSIGNED NOT NULL, 
     `time` INT UNSIGNED NOT NULL DEFAULT 0, 
     `kills` MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, 
     `deaths` MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, 
     PRIMARY KEY(`pid`,`id`), 
     FOREIGN KEY(`pid`) REFERENCES player(`id`) ON DELETE CASCADE ON UPDATE CASCADE, 
     FOREIGN KEY(`id`) REFERENCES kit(`id`) ON DELETE RESTRICT ON UPDATE CASCADE 
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

    ALTER TABLE `bf2stats`.`player_kit` ADD INDEX `reverse_ids` (`id`, `pid`); 


    -- 
    -- My Full Scanning Query 
    -- SELECTS players, ordering them by kills and time in kit 
    -- 
    SELECT p.name, p.rank, p.country, k.pid, k.kills, k.deaths, k.time 
    FROM player_kit AS k 
     INNER JOIN player AS p ON k.pid = p.id 
    WHERE k.id = 0 AND k.kills > 0 
    ORDER BY kills DESC, time DESC 
    LIMIT 0, 40 

    -- 
    -- EXPLAIN results by MySQL 
    -- 
    id select_type table partitions type possible_keys key key_len ref rows filtered Extra 
    1 SIMPLE k NULL ref PRIMARY 1 const 75 32.11 Using index condition; Using where; Using filesort 
    1 SIMPLE p NULL eq_ref PRIMARY PRIMARY 4 bf2stats.k.pid 1 100.00 NULL 

    -- 
    -- Additional Tables just in case, for reference 
    -- 
    -- 
    -- Table structure for table `kit` 
    -- 

    CREATE TABLE `kit` (
     `id` TINYINT UNSIGNED, 
     `name` VARCHAR(32) NOT NULL, 
     PRIMARY KEY(`id`) 
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

    -- 
    -- Table structure for table `player` 
    -- 

    CREATE TABLE `player` (
     `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, 
     `name` VARCHAR(32) UNIQUE NOT NULL, 
     `rank` TINYINT NOT NULL DEFAULT 0, 
     `country` CHAR(2) NOT NULL DEFAULT 'xx', 
     PRIMARY KEY(`id`) 
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

はphpMyAdminのから説明しています私がそれに付けたインデックスは、あまり役に立たないようです。このクエリの

+1

インデックス 'player_kit(id、kills、time)'が必要です。 – Solarflare

答えて

1

SELECT p.name, p.rank, p.country, k.pid, k.kills, k.deaths, k.time 
FROM player_kit k INNER JOIN 
    player p 
    ON k.pid = p.id 
WHERE k.id = 0 AND k.kills > 0 
ORDER BY kills DESC, time DESC 
LIMIT 0, 40; 

最適なインデックスは、次のとおりです。

  • player_kit(id, kills, pid)
  • player(id) - これがすでに

でない場合にも追加することができます索引内の他の列を使用して問合せのカバー索引を取得します。