【发布时间】:2018-06-17 16:11:03
【问题描述】:
我有 3 张桌子:
# config - only 1 line in table
# Config (maxCount int)
Create Table Config(maxCount int)
# files- 20k lines in table
# Files(fileid int (pk), filename varchar (unique), revCount int)
Create Table Files (
fileid int(10) unsigned not null auto_increment,
filename varchar(255) not null,
revCount int(10) unsigned default 1,
primary key(fileid),
unique key filename(filename)
);
# Revitions - 26k lines in table
# Revisions(revid (pk), fileid int (fk), revname varchar,...)
create table Revisions(
revid int(10) unsigned not null auto_increment,
fileid int(10) unsigned not null,
revname varchar(255) not null,
mtime timestamp default CURRENT_TIMESTAMP,
deleted boolean default false,
primary key(revid),
KEY fr_fileid_fk_idx (fileid),
CONSTRAINT fr_fileid_fk FOREIGN KEY(fileid)
REFERENCE Files(fileid)
ON DELETE CASCADE ON UPDATE CASCADE
);
并具有以下存储过程:
create procedure test1(in file_id int,out max_count int, out rev_count int, out last_revid int)
begin
select maxCount into max_count from Config limit 1;
select revCount into rev_count from Files where fileid=file_id;
select max(revid) into last_revid from Revitions where fileid=file_id;
end
我通过为文件 (20k) 中的每个 fileid 调用它来检查 test1 的性能,调用它大约需要 2.7 秒才能运行
测试过程是:
create procedure t1()
begin
declare done int default 0;
declare file_id,last_revid,max_count,rev_cout int default 0;
declare c1 cursor for select fileid from files;
declare continue handle for not found select 1 into done from (select 1) as t;
open c1;
read1: loop
fetch c1 into file_id;
if done=1 then
leave read1;
end if;
call test1(file_id, max_count,rev_cout,last_revid);
end loop;
close c1;
end
我尝试了其他解决方案,将 3 个选择统一为 1 个查询,如下所示:
create procedure test2(in file_id int,out max_count int, out rev_count int, out last_revid int)
begin
select maxCount, revCount, max(revid)
into max_count,rev_count,last_revid
from Config, Files, Revitions
where Files.fileid=file_id AND Revitions.fileid=file_id
limit 1;
end
我通过将call test1 更改为call test2 将t1 更改为t2
结果是性能显着提高,第二个 (t2) 花了大约 2 秒(效率提高了 25%!),我重复测试了很多次,结果始终相同。
有什么原因吗?
我认为表的连接效率较低,然后从每个表中单独选择,但显然第二个更快。
所以我可以指望它并且总是更喜欢统一来自多个表的选择查询,还是应该检查每种情况下哪个是最好的?
【问题讨论】:
-
您是否尝试过对这些查询中的任何一个运行
EXPLAIN? -
@TimBiegeleisen 没有,只在 mysql workbench 中检查查询持续时间。
-
不要忘记连续两次运行相同的查询会产生异常的计时结果。在尝试获得可重现的查询时间时,使用
SELECT SQL_NO_CACHE ...来避免这个问题。另外,请阅读此内容。 meta.stackoverflow.com/a/271056 请特别注意查询性能部分。请edit您的问题提供更多详细信息。事实上,你只是在让我们猜测。 -
@O.Jones 谢谢,我添加了 create table 语句,使用 SQL_NO_CACHE 进行统一选择的持续时间稍长一些,但性能仍然提高了 20%-25%。跨度>
标签: mysql select stored-procedures query-performance