我正在尝试理解我在等效代码中看到的巨大性能差异。或者至少代码我认为是等价的。
我有一张表上有大约1000万条记录。它包含一个字段,索引定义为: USPatentNum char(8)
如果我将带有MySql的变量设置为某个值,则需要218秒。使用字符串文字的完全相同的查询不到1/4秒。
在下面的代码中,第一个select语句(其中USPatentNum = @pn;)需要永远,但第二个,带有字面值 (其中USPatentNum ='5288812';)几乎是即时的
mysql> select @pn := '5288812'; +------------------+ | @pn := '5288812' | +------------------+ | 5288812 | +------------------+ 1 row in set (0.00 sec) mysql> select patentId, USPatentNum, grantDate from patents where USPatentNum = @pn; +----------+-------------+------------+ | patentId | USPatentNum | grantDate | +----------+-------------+------------+ | 306309 | 5288812 | 1994-02-22 | +----------+-------------+------------+ 1 row in set (3 min 38.17 sec) mysql> select @pn; +---------+ | @pn | +---------+ | 5288812 | +---------+ 1 row in set (0.00 sec) mysql> select patentId, USPatentNum, grantDate from patents where USPatentNum = '5288812'; +----------+-------------+------------+ | patentId | USPatentNum | grantDate | +----------+-------------+------------+ | 306309 | 5288812 | 1994-02-22 | +----------+-------------+------------+ 1 row in set (0.21 sec)
两个问题:
为什么使用@pn这么慢? 我可以更改select语句,以便性能相同吗?
答案 0 :(得分:1)
在设置值之前将@pn声明为char(8)。
我怀疑它现在就是varchar。如果是这样,性能损失是因为MySql无法使用您的变量加载索引。
答案 1 :(得分:-1)
使用常量还是@var无关紧要。你得到不同的结果,因为MySQL第二次从缓存中获得结果。如果你再次执行你的场景但交易将查询与const和@var放在一起,你会得到相同的结果(但是有另一个值)。第一个会慢,第二个会很快。
希望有所帮助