Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql (1) 使用基于函数的索引或(2)仅为时间创建一个新列,为该列编制索引并在您的SELECT子句中使用它_Sql_Sql Server_Datetime - Fatal编程技术网

Sql (1) 使用基于函数的索引或(2)仅为时间创建一个新列,为该列编制索引并在您的SELECT子句中使用它

Sql (1) 使用基于函数的索引或(2)仅为时间创建一个新列,为该列编制索引并在您的SELECT子句中使用它,sql,sql-server,datetime,Sql,Sql Server,Datetime,请记住,如果在SQL的WHERE子句中使用函数,则引擎必须执行扫描搜索,否则将失去任何索引性能提升。只需使用EXPLAIN SELECT…运行查询即可确认这一点。这是因为引擎必须为每次比较处理字段中的每个值,并且转换后的值没有索引 大多数答案说使用float(),convert(),cast(),addtime(),等等。。同样,如果这样做,数据库将不会使用索引。对于小桌子,这可能还可以 尽管(WHERE field=func(value))可以在WHEREparams中使用函数,因为您不会更改

请记住,如果在SQL的
WHERE
子句中使用函数,则引擎必须执行扫描搜索,否则将失去任何索引性能提升。只需使用
EXPLAIN SELECT…
运行查询即可确认这一点。这是因为引擎必须为每次比较处理字段中的每个值,并且转换后的值没有索引

大多数答案说使用
float()
convert()
cast()
addtime()
,等等。。同样,如果这样做,数据库将不会使用索引。对于小桌子,这可能还可以

尽管(
WHERE field=func(value)
)可以在
WHERE
params中使用函数,因为您不会更改表中每个字段的值

如果希望继续使用索引,可以为时间值创建基于函数的索引。正确的方法(以及对它的支持)可能取决于您的数据库引擎。另一个选项是添加一列以仅存储时间值并索引此列,但请先尝试前一种方法


编辑06-02
在更新数据库以使用新的时间列或其他任何索引之前,请执行一些性能测试。在测试中,我发现性能提升很小(当我看到一些改进时),不值得添加新索引的麻烦和开销。

Chris,为什么我必须转换为VARCHAr来比较时间?这样,我就可以比较字符串和字符串了吗?原因有二:1)CONVERT()方法用于从一种类型转换为另一种类型;如果将DATETIME转换为DATETIME,则不会发生任何事情。2) CONVERT()的第三个参数(8)是用于在转换为字符串类型时格式化数据的代码;转换为DATETIME时没有任何意义。强制转换为INT-rounds,这会使结果不总是准确的,FLOOR是获取示例的方法。这就是示例的原因:基于日期舍入,因此我们可以只处理时间字段。你测试过了吗?太棒了,谢谢!我已经做了很多varchar转换,这似乎是一个更好的方法(虽然看起来不是很明显)。为什么我必须转换为varchar,以便比较一个时间是否大于另一个时间?我会用这种方法比较字符串和字符串吗?DateDiff函数接受datetime字段作为输入,这样可以克服困难。注意:这种方法的性能似乎不太好
SELECT timeEvent 
FROM tbEvents 
WHERE convert(datetime, startHour, 8) >= convert(datetime, @startHour, 8)
SELECT timeEvent 
  FROM tbEvents 
 WHERE CONVERT(VARCHAR,startHour,108) >= '01:01:01'
SELECT timeEvent
FROM tbEvents
WHERE convert(VARCHAR(8), startHour, 8) >= convert(VARCHAR(8), @startHour, 8)
CREATE FUNCTION dbo.f_trimdate (@dat datetime) RETURNS DATETIME AS BEGIN
    RETURN CONVERT(DATETIME, CONVERT(FLOAT, @dat) - CONVERT(INT, @dat))
END
DECLARE @dat DATETIME
SELECT @dat = '20080201 02:25:46.000'
SELECT dbo.f_trimdate(@dat)
WHERE CONVERT(time(0), startHour) >= CONVERT(time(0), @startTime)
DECLARE @tbEvents TABLE (
    timeEvent   int      IDENTITY,
    startHour   datetime
)

INSERT INTO @tbEvents (startHour) SELECT DATEADD(hh, 0, GETDATE())
INSERT INTO @tbEvents (startHour) SELECT DATEADD(hh, 1, GETDATE())
INSERT INTO @tbEvents (startHour) SELECT DATEADD(hh, 2, GETDATE())
INSERT INTO @tbEvents (startHour) SELECT DATEADD(hh, 3, GETDATE())
INSERT INTO @tbEvents (startHour) SELECT DATEADD(hh, 4, GETDATE())
INSERT INTO @tbEvents (startHour) SELECT DATEADD(hh, 5, GETDATE())

--SELECT * FROM @tbEvents

DECLARE @startTime  datetime

SET @startTime = DATEADD(mi, 65, GETDATE())

SELECT
    timeEvent,
    CONVERT(time(0), startHour)  AS 'startHour',
    CONVERT(time(0), @startTime) AS '@startTime'
FROM @tbEvents
WHERE CONVERT(time(0), startHour) >= CONVERT(time(0), @startTime)
convert(varchar(5), thedate, 108) between @leftTime and @rightTime
declare @first datetime
set @first = '2009-04-30 19:47:16.123'
declare @second datetime
set @second = '2009-04-10 19:47:16.123'

select (cast(@first as float) - floor(cast(@first as float))) -
       (cast(@second as float) - floor(cast(@second as float)))
       as Difference
declare @mydate datetime
set @mydate = '2009-04-30 19:47:16.123'
declare @myfloat float
set @myfloat = cast(@mydate as float)
select @myfloat
-- Shows 39931,8244921682
set @myfloat = @myfloat - floor(@myfloat) 
select @myfloat
-- Shows 0,824492168212601
declare @mytime datetime
set @mytime = convert(datetime,@myfloat)
select @mytime
-- Shows 1900-01-01 19:47:16.123
select convert(varchar(32),@mytime,108)
-- Shows 19:47:16
DECLARE @t1 datetime, @t2 datetime
SELECT @t1 = '19000101 23:55:00', @t2 = '20001102 23:55:00'
SELECT CAST(@t1 as float) - floor(CAST(@t1 as float)), CAST(@t2 as float) - floor(CAST(@t2 as float))
declare  @date1 datetime;
declare  @date2 datetime;

select   @date1 = CONVERT(varchar(20),CONVERT(datetime, '2011-02-11 08:00:00'), 114)
select   @date2 = CONVERT(varchar(20),GETDATE(), 114)
if @date1 <= @date2
   print '@date1 less then @date2'
else
   print '@date1 more then @date2'
select DateAdd(day,-DateDiff(day,0,YourDateTime),YourDateTime) As NewTime from Table
if (cast('2012-06-20 23:49:14.363' as time) between 
    cast('2012-06-20 23:49:14.363' as time) and 
    cast('2012-06-20 23:49:14.363' as time))
Create Function [dbo].[MsFromStartOfDay] ( @DateTime datetime )
Returns int
As
  Begin
      Return (
               ( Datepart( ms , @DateTime ) ) +
               ( Datepart( ss , @DateTime ) * 1000 ) +
               ( Datepart( mi , @DateTime ) * 1000 * 60 ) +
               ( Datepart( hh , @DateTime ) * 1000 * 60 * 60 )
              )
  End
declare @first datetime
set @first = '1900-01-01 23:59:39.090'
declare @second datetime
set @second = '2000-11-02 23:56:39.090'
Select dbo.MsFromStartOfDay( @first )
Select dbo.MsFromStartOfDay( @second )
set @first = '1900-01-01 23:59:39.556'
set @second = '2000-11-02 23:56:39.556'
SELECT timeEvent 
FROM tbEvents 
WHERE convert(time, startHour) >= convert(time, @startHour)