SQL什么是更快的左2或转换(varchar(2),'Chgffgjjx')

时间:2010-02-10 18:11:05

标签: sql sql-server string

如果我想返回字符串的前两个字符,这是最好/最快的方法?

此外,如果我有一个约会并希望按天分组,我会使用convert(varchar(10),getdate()) 因为我们的数据库格式是yyyy / MM / dd,如果我想按月分组,我会使用varchar(7)代替'2010/02'

有没有更快的方法来实现同样的目标?

6 个答案:

答案 0 :(得分:3)

这两者之间的表现没有差别。但是 - 从您的问题来看,这一点并不完全清楚 - 如果您将其置于WHERE条件而不是查询的列输出,则两者都非常非常糟糕。

LEFTSUBSTRINGCONVERT等字符串函数(当用于转换时)是不可搜索的,这意味着通常有效的索引查找将变为昂贵的完整索引扫描。如果要查询字段的前两个字符,则应编写查询:

SELECT Col1, Col2, ...
FROM Table
WHERE StringCol LIKE 'AB%'

同样,这仅适用于过滤器;如果LEFT / SUBSTRING位于列输出中(即SELECT LEFT(Col1, 2)),那么您无需担心性能。

答案 1 :(得分:1)

查询的计算标量部分的结果与使用LEFT(t.col, 2)CONVERT(VARCHAR(2), t.col)相同:

Estimated CPU Cost:       0.0283193
Estimated I/O Cost:       0
Estimated Number of Rows: 283193
Estimated Operator Cost:  0.028 (0%)

SQL Server 2005

我的假设是LEFT是CAST / CONVERT ...

的同义词

答案 2 :(得分:1)

1)如果我想返回字符串的前两个字符,这是最好/最快的方法吗?

LEFT('YourString',2)是恕我直言,在喊叫和尖叫的意图方面更自然,更具可读性。我真的不认为这会导致性能不佳 - 更有可能因为构造不良的查询,缺少索引等而导致性能不佳。我只会坚持使用自然,最简单的方法。


2)如果我有一个日期并希望按天分组,我将使用convert(varchar(10),getdate()),因为我们的db格式是yyyy / MM / dd,这将给出'2010/02/10'如果我想按月分组,我会使用varchar(7)代替'2010/02'

转换日期时,我总是指定CONVERT的最后一个参数,即样式。 e.g。

-- 112 = ISO format. This would give yyyyMM
SELECT CONVERT(VARCHAR(6), GETDATE(), 112) 

请注意,这是我上面所说的一个很好的例子:其他领域更可能表现更差。如果将CONVERT应用于查询的WHERE子句中的列,则会阻止使用该列上的索引。因此,我会将查询更改为指定日期范围,包括开始日期=月初日期和结束日期=下个月的第1天:

SELECT * 
FROM SomeTable
WHERE DateField >= @StartOfMonth AND DateField < @FirstDayOfNextMonth

这将使用DateField上的索引,提供比CONVERT方法更好的性能

答案 3 :(得分:1)

至于你的第二个问题:如果你在一个更大的桌子上操作,不要使用这个CONVERT()方法。一种更有效的方法是使用像

这样的东西
GROUP BY DATEADD(DAY, DATEDIFF(DAY, 0, < your datetime column >), 0) 

按天分组,同样

GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, < your datetime column >), 0) 

按月分组。

答案 4 :(得分:0)

A1。 LEFT当然,除了使用明确只做那个的函数之外,你怎么能做更少的工作呢?

A2。不要将DATE存储为varchars,将它们存储为日期并将它们编入索引,这样可以快速点亮,并且您可以使用DATEPART来获取日期的某些组成部分。

答案 5 :(得分:-1)

测试出来:

DECLARE @x int
       ,@RunDate datetime
       ,@y  char(2)
       ,@z int
       ,@total int
       ,@tries int

SELECT @z=1,@total=0,@tries=20

WHILE @z<=@tries
BEGIN
    SELECT @RunDate=GETDATE(),@x=1,@z=@z+1
    WHILE @x<500000
    BEGIN
       SET @x=@x+1
       SELECT @x=@x+1,@y=LEFT('Chgffgjjx',2)
    END
    PRINT RIGHT(' '+CONVERT(varchar(2),@z-1),2)+' - LEFT() Took: '+CONVERT(varchar(20),datediff(ms,@RunDate,GETDATE()))+' milliseconds'
    SET @total=@total+CONVERT(varchar(20),datediff(ms,@RunDate,GETDATE()))
END
PRINT 'LEFT() average: '+CONVERT(varchar(20),@total/(1.0+@tries))
SELECT @z=1,@total=0,@tries=20
WHILE @z<=@tries
BEGIN

    SELECT @RunDate=GETDATE(),@x=1,@z=@z+1
    WHILE @x<500000
    BEGIN
       SET @x=@x+1
       SELECT @x=@x+1,@y=CONVERT(varchar(2),'Chgffgjjx')
    END
    PRINT RIGHT(' '+CONVERT(varchar(2),@z-1),2)+' - CONVERT() Took: '+CONVERT(varchar(20),datediff(ms,@RunDate,GETDATE()))+' milliseconds'
    SET @total=@total+CONVERT(varchar(20),datediff(ms,@RunDate,GETDATE()))
END
PRINT 'CONVERT() average: '+CONVERT(varchar(20),@total/(1.0+@tries))

输出:

 1 - LEFT() Took: 563 milliseconds
 2 - LEFT() Took: 390 milliseconds
 3 - LEFT() Took: 406 milliseconds
 4 - LEFT() Took: 390 milliseconds
 5 - LEFT() Took: 390 milliseconds
 6 - LEFT() Took: 390 milliseconds
 7 - LEFT() Took: 393 milliseconds
 8 - LEFT() Took: 390 milliseconds
 9 - LEFT() Took: 390 milliseconds
10 - LEFT() Took: 486 milliseconds
11 - LEFT() Took: 686 milliseconds
12 - LEFT() Took: 453 milliseconds
13 - LEFT() Took: 390 milliseconds
14 - LEFT() Took: 406 milliseconds
15 - LEFT() Took: 403 milliseconds
16 - LEFT() Took: 410 milliseconds
17 - LEFT() Took: 560 milliseconds
18 - LEFT() Took: 546 milliseconds
19 - LEFT() Took: 593 milliseconds
20 - LEFT() Took: 390 milliseconds
LEFT() average: 429.7619047619047
 1 - CONVERT() Took: 440 milliseconds
 2 - CONVERT() Took: 513 milliseconds
 3 - CONVERT() Took: 393 milliseconds
 4 - CONVERT() Took: 453 milliseconds
 5 - CONVERT() Took: 390 milliseconds
 6 - CONVERT() Took: 406 milliseconds
 7 - CONVERT() Took: 420 milliseconds
 8 - CONVERT() Took: 406 milliseconds
 9 - CONVERT() Took: 390 milliseconds
10 - CONVERT() Took: 390 milliseconds
11 - CONVERT() Took: 406 milliseconds
12 - CONVERT() Took: 390 milliseconds
13 - CONVERT() Took: 626 milliseconds
14 - CONVERT() Took: 593 milliseconds
15 - CONVERT() Took: 423 milliseconds
16 - CONVERT() Took: 406 milliseconds
17 - CONVERT() Took: 450 milliseconds
18 - CONVERT() Took: 486 milliseconds
19 - CONVERT() Took: 406 milliseconds
20 - CONVERT() Took: 390 milliseconds
CONVERT() average: 417.9523809523809
他们似乎非常接近我