使用变量时sql语句速度慢

lg40wkob  于 2021-06-17  发布在  Mysql
关注(0)|答案(2)|浏览(356)

我在mariadb 10.1.26上运行了下面的sql语句,其中包含约2.000行的即时结果。

select value, datetime from Schuppen 
where (value = (select min(value) from Schuppen where (measure = 'temp') 
    and datetime between '2018-11-01 00:00:00' and '2018-11-02 00:00:00')) 
and datetime between '2018-11-01 00:00:00' and '2018-11-02 00:00:00';

当我将下面的语句与datetime字段的变量一起使用时,执行大约需要5.5秒。

set @startdate = cast('2018-11-01 00:00:00' as datetime);
set @enddate = cast('2018-11-02 00:00:00' as datetime);
select value, datetime from Schuppen 
where (value = (select min(value) from Schuppen where (measure = 'temp') 
    and datetime between @startdate and @enddate)) 
and datetime between @startdate and @enddate;

我拥有的数据行越多,执行语句的时间就越长。似乎变量以某种方式改变了语句的行为。
这里怎么了?

dl5txlt9

dl5txlt91#

问题是在使用变量时,查询优化器在寻找合适的索引方面做得不好。这是一个已知的问题。
如果你使用 EXPLAIN 在这两个查询中,您将看到不同之处。在不必要的时候尽量避免变量。
对于第一个查询,优化器“看到”所选的值,并决定可以完美地使用索引来更有效地满足所选范围。
对于第二个查询,优化器不知道定义范围的两个值,而是决定退回到完全扫描。

toe95027

toe950272#

我使用mysql workbench和@variables来查询/搜索给定属性的不同表非常有用。我也遇到了类似的问题。在浏览了不同的线程并尝试了不同的操作之后,当我将@variable设置为与我正在搜索的表中的列的类型和编码完全相同时,它工作得很好。
例如:

SET @keyword = CONVERT(CAST("KEYWORD" AS CHAR(8)) USING ASCII);

在本例中,我的customer表中的搜索列cname是char(8)类型,并使用ascii编码:

SELECT * FROM CUSTOMERS WHERE cname=@keyword;

如果要查询多个表,其中cname在一个表中为char(10),在另一个表中为char(8),则可以执行以下操作:

SET @keyword = "KEYWORD";
SELECT * FROM CUSTOMERS WHERE cname=CONVERT(CAST(@keyword AS CHAR(8)) USING ASCII);
SELECT * FROM EMPLOYEES WHERE cname=CONVERT(CAST(@keyword AS CHAR(10)) USING ASCII);

相关问题