我在Windows Server 2008(使用4GB RAM)上使用MySQL 5.1并具有以下配置:
我有2个MyISAM表。一个是在1个数据库(DB1)中,有14列,主要是varchar。该表有大约5,000,000行,下面是DB1.games表。它在GameNumber(int(10))上有一个主键。
另一个表是DB2.gameposition,由GameNumber列组成(链接到 DB1.games)和PositionCode(int(10))。该表有大约400,000,000行,并且在PositionCode上有一个索引IX_PositionCode。
这两个数据库位于同一台服务器上。
我想在DB2.gameposition上运行查询以查找特定的PositionCode,并将结果按链接DB1.games.Yr字段排序(smallint(6) - 这表示年份)。我最近才介绍的结果排序。 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;
我只需要1000就可以更快地使用
然后将其加入DB1.games表。
为了从中生成一个EXPLAIN,我取出了临时表(我在存储过程中使用)并重构它,如下面的内部子查询所示:
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
运行上面的EXPLAIN,我看到以下内容:
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'
在我引入ORDER BY子句之前,查询几乎是即时的。现在,有时它很快(取决于不同的PositionCode),但有时它可能需要10秒才能返回行。在我介绍排序之前,它总是几乎是瞬间完成的。不幸的是,我不太精通解释EXPLAIN输出。或者如何更快地进行查询。
非常感谢任何帮助!
提前致谢, 添
答案 0 :(得分:0)
如果没有order by
,则limit
表示返回前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 ...