Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL MyISAM排序查询使其速度变慢_Mysql_Performance_Sorting_Sql Order By_Myisam - Fatal编程技术网

MySQL MyISAM排序查询使其速度变慢

MySQL MyISAM排序查询使其速度变慢,mysql,performance,sorting,sql-order-by,myisam,Mysql,Performance,Sorting,Sql Order By,Myisam,我在具有4GB RAM的Windows Server 2008上使用MySQL 5.1,并具有以下配置: 我有两张MyISAM桌子。一个在数据库DB1中,有14列,其中大部分是varchar。这个表大约有5000000行,是下面的DB1.games表。它在游戏编号int10上有一个主键 另一个表是DB2.gameposition,由GameNumber链接列组成 DB1.1游戏和位置代码int10。该表约有400000000行,位置代码上有一个索引IX_PositionCode 这两个数据库位于

我在具有4GB RAM的Windows Server 2008上使用MySQL 5.1,并具有以下配置:

我有两张MyISAM桌子。一个在数据库DB1中,有14列,其中大部分是varchar。这个表大约有5000000行,是下面的DB1.games表。它在游戏编号int10上有一个主键

另一个表是DB2.gameposition,由GameNumber链接列组成 DB1.1游戏和位置代码int10。该表约有400000000行,位置代码上有一个索引IX_PositionCode

这两个数据库位于同一台服务器上

我想在DB2.gameposition上运行一个查询,以找到一个特定的PositionCode,并将结果按链接的DB1.games.Yr字段smallint6排序——这表示一年。这是我最近才介绍的结果排序。在DB1.games中,这个Yr字段上有一个索引

在存储过程中,我执行以下操作:

CREATE TEMPORARY TABLE tblGameNumbers(GameNumber INT UNSIGNED NOT NULL PRIMARY KEY);

INSERT INTO tblGameNumbers(GameNumber) 
SELECT DISTINCT gp.GameNumber 
FROM DB2.gameposition gp 
WHERE PositionCode = var_PositionCode LIMIT 1000;
1, 'PRIMARY', '', 'ALL', '', '', '', '', 1000, 'Using temporary; Using filesort' 1, 'PRIMARY', 'g', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'B.GameNumber', 1, '' 2, 'DERIVED', 'gp', 'ref', 'IX_PositionCode', 'IX_PositionCode', '4', '', 1889846, 'Using temporary' 我只得到1000英镑,让它更快

然后将其连接到DB1.games表

为了从中生成解释,我取出了存储过程中使用的临时表,并对其进行了重构,如下面的内部子查询所示:

EXPLAIN 
SELECT * 
FROM DB1.games g 
INNER JOIN (SELECT DISTINCT gp.GameNumber 
            FROM DB2.gameposition gp 
            WHERE PositionCode = 669312116 LIMIT 1000
   ) B ON g.GameNumber = B.GameNumber 
ORDER BY g.Yr DESC 
LIMIT 0,28
运行上面的解释,我看到以下内容:

CREATE TEMPORARY TABLE tblGameNumbers(GameNumber INT UNSIGNED NOT NULL PRIMARY KEY);

INSERT INTO tblGameNumbers(GameNumber) 
SELECT DISTINCT gp.GameNumber 
FROM DB2.gameposition gp 
WHERE PositionCode = var_PositionCode LIMIT 1000;
1, 'PRIMARY', '', 'ALL', '', '', '', '', 1000, 'Using temporary; Using filesort' 1, 'PRIMARY', 'g', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'B.GameNumber', 1, '' 2, 'DERIVED', 'gp', 'ref', 'IX_PositionCode', 'IX_PositionCode', '4', '', 1889846, 'Using temporary' 在我引入ORDERBY子句之前,查询几乎是即时的。现在,根据不同的位置代码,有时返回速度很快,但有时返回行最多需要10秒。在我引入排序之前,它几乎总是即时的。不幸的是,我不太擅长解释输出。或者如何使查询更快

任何帮助都将不胜感激

提前感谢,, Tim

如果没有order by,您的限制意味着返回前28个结果,然后查询停止。使用order by,需要检索所有结果,以便对它们进行排序并返回前28个结果

解释显示了MySql正在做什么:

sort 5000000 games records by yr
for each games record from sorted list
    get the games record by primary key (to get all the columns)
    read gamepositions by position code
        if it does not match gamenumber, discard it
        when 1000 matches found, stop reading
    end read
end for
请尝试以下方法:

select distinct ... from gameposition gp
inner join games g on g.gamenumber = gp.gamenumber
where gp.positioncode = ...
order by g.yr limit ...

您好,谢谢您的回复…我只对1000行进行排序,因为我将它们限制为1000行,所以我不明白为什么这需要很长时间…我需要在限制它们之前获得这1000行,否则按顺序排序就没有意义了…不幸的是,MySQl没有使用我们所看到的最有效的算法。请参阅更新的answer.SELECT*FROM SELECT DISTINCT GameNumber FROM DB2.gameposition gp internal join games g on g.GameNumber=gp.GameNumber WHERE PositionCode=669312116 order by g.yr DESC limit 0,28,但这需要很长的时间,只要在连接后应用WHERE子句…从而有效地连接两个非常大的表…如果我放置以下从DB2.gameposition gp中选择DISTINCT gp.GameNumber,其中PositionCode=669312116 LIMIT 1000我正在加入一个物理表tmp并运行:EXPLAIN SELECT*FROM DB1.games g internal JOIN tmp B on g.GameNumber=B.GameNumber ORDER BY g.Yr DESC LIMIT 0,28执行计划变得更好没有派生、文件排序或临时。在sp中,我创建了一个临时表,在其中插入1000个匹配的游戏号码,然后如上所述加入。执行计划是否受连接到物理表还是临时表的影响?谢谢我忘了提到我用于测试的phsyic表tmp和存储过程中的临时表都有以下字段:GameNumber UNSIGNED INT NOT NULL主键。因此,可能主键使连接比为解释带有子查询的查询而修改的查询更快。如果是这样的话,我仍然不明白为什么有时它是缓慢的。。。