如果我想返回字符串的前两个字符,这是最好/最快的方法?
此外,如果我有一个约会并希望按天分组,我会使用convert(varchar(10),getdate())
因为我们的数据库格式是yyyy / MM / dd,如果我想按月分组,我会使用varchar(7)
代替'2010/02'
有没有更快的方法来实现同样的目标?
答案 0 :(得分:3)
这两者之间的表现没有差别。但是 - 从您的问题来看,这一点并不完全清楚 - 如果您将其置于WHERE
条件而不是查询的列输出,则两者都非常非常糟糕。
LEFT
,SUBSTRING
和CONVERT
等字符串函数(当用于转换时)是不可搜索的,这意味着通常有效的索引查找将变为昂贵的完整索引扫描。如果要查询字段的前两个字符,则应编写查询:
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
他们似乎非常接近我