我对数据库管理还是个新手,我正在尝试优化搜索查询。
我有一个看起来像这样的查询,在某些情况下需要 5-15 秒来执行,并且还导致 100% 的 CPU 使用率:
DECLARE @point geography;
SET @point = geography::STPointFromText('POINT(3.3109015 6.648294)', 4326);
SELECT TOP (1)
[Result].[PointId] AS [PointId],
[Result].[PointName] AS [PointName],
[Result].[LegendTypeId] AS [LegendTypeId],
[Result].[GeoPoint] AS [GeoPoint]
FROM (
SELECT
[Extent1].[GeoPoint].STDistance(@point) AS distance,
[Extent1].[PointId] AS [PointId],
[Extent1].[PointName] AS [PointName],
[Extent1].[LegendTypeId] AS [LegendTypeId],
[Extent1].[GeoPoint] AS [GeoPoint]
FROM [dbo].[GeographyPoint] AS [Extent1]
WHERE 18 = [Extent1].[LegendTypeId]
) AS [Result]
ORDER By [Result].distance ASC
Run Code Online (Sandbox Code Playgroud)
该表在 PK 上有一个聚集索引,在geography
类型列上有一个空间索引。
所以当我执行上述查询时,它正在执行扫描操作。
所以我在LegendTypeId
列上创建了一个非聚集索引:
CREATE NONCLUSTERED INDEX [GeographyPoint_LegendType_NonClustered] ON [dbo].[GeographyPoint] …
Run Code Online (Sandbox Code Playgroud) performance index sql-server optimization spatial query-performance
数据库管理系统:SQL Server 2012 Express
我有一个看起来像这样的 SQL 语句:
SELECT
OverSpeedings = SUM(OverSpeeding),
OverspeedingPoints = SUM(OverSpeeding) * 5,
FROM
MyTable
GROUP BY
COLUMNS_HERE
Run Code Online (Sandbox Code Playgroud)
我想知道两次添加同一列是否会影响性能?意思是 SQL Server 两次添加列吗?或者它会添加一次列并用于结果集中的两列?
或者我应该使用具有SUM
以下内容的 CTE :
SELECT
OverSpeedings,
OverspeedingPoints = OverSpeedings * 5,
FROM
(
SELECT
OverSpeedings = SUM(OverSpeeding)
FROM
MyTable
GROUP BY
COLUMNS_HERE
) A
Run Code Online (Sandbox Code Playgroud) 我正在处理我们通过夜间开始时间和夜间结束时间的程序,我需要在这些时间之间获取日志。
所以:
StartHour = 18
and EndHour = 5
,存储过程应该返回6:00 PM
和之间的所有日志5:00 AM
。StartHour = 1
and EndHour = 5
,存储过程应该返回1:00 AM
和之间的所有日志5:00 AM
。我尝试创建 SQL Fiddle,但在今天的 SQL Server 2014 或 SQL Server 2008 中创建小提琴似乎存在问题。
我正在使用 SQL SERVER 2014 - 但 Fiddle 在 MySQL 中
(我在 MySQL 中创建了一个来显示数据)[错误的小提琴:http ://sqlfiddle.com/#!9/6f0a6/1 ]
正确:http ://sqlfiddle.com/#!9/ 6467d8/3
这是我的脚本的样子:
Select
*
FROM
(
Select
iVehicleMonitoringId,
dtUtcDateTime,
HourPart = DATEPART(HOUR, dtUtcDateTime)
From VehicleMonitoringLog vm
Where vm.dtUTCDateTime …
Run Code Online (Sandbox Code Playgroud) 我有一个存储过程,它正在计算一些数据并将其插入到临时表中。
然后我从临时表中选择数据。
Select
AssetId = iAssetId,
.....
SpeedKM = fSpeed,
[Address] = sState +', '+ sDistrict +', ' +sPoi +', ' + sRoad +', '+sPoi,
MapUrl = @sUrlHeader+'/Report/ReportOnMap/?id='
+CONVERT(VARCHAR(10), @iCompanyId)+'&ReportName=OverspeedReport'
+'&AssetId='+ CONVERT(VARCHAR(10), iAssetId)
+'&MaxSpeed='+ CONVERT(VARCHAR(10), fSpeed)
+'&OverspeedingDate=' + FORMAT(dtutcDateTime, 'dd-MMM-yyyy HH:mm:ss')
+'&VehicleMonitoringLogId='+ CONVERT(VARCHAR, ol.iVehicleMonitoringId),
[Locate] = 'Locate'
FROM #overspeedLogs ol
ORDER BY ol.iAssetId, ol.dtUtcDateTime
Run Code Online (Sandbox Code Playgroud)
现在这个查询大约需要 1:45 分钟来执行。
但是当我删除列时
MapUrl = @sUrlHeader+'/Report/ReportOnMap/?id='
+CONVERT(VARCHAR(10), @iCompanyId)+'&ReportName=OverspeedReport'
+'&AssetId='+ CONVERT(VARCHAR(10), iAssetId)
+'&MaxSpeed='+ CONVERT(VARCHAR(10), fSpeed)
+'&OverspeedingDate=' + FORMAT(dtutcDateTime, 'dd-MMM-yyyy HH:mm:ss')
+'&VehicleMonitoringLogId='+ CONVERT(VARCHAR, ol.iVehicleMonitoringId),
Run Code Online (Sandbox Code Playgroud)
存储过程只需要35 seconds …
我需要计算DATEDIFF
每个日期的第一条记录与每个日期EventCode = 1
的最后一条记录之间的秒数EventCode = 2
。
我在这里发布了 2 天的示例数据集:http : //data.stackexchange.com/dba/query/515591/calculate-the-difference-between-first-event-and-last-event-for-each-日期
所以这就是我如何获得每个日期的第一条记录:
Select
LogDate,
StartOfDay = MIN(LogDateTime),
EventCode
FROM (
Select
LogId,
LogDateTime,
LogDate = FORMAT(LogDateTime, 'dd-MMM-yyyy'),
DriverId,
EventCode
FROM
#MyLogs
WHERE EventCode = 1
) A
Group By
LogDate, EventCode
Run Code Online (Sandbox Code Playgroud)
这就是我获取每个日期的最后记录的方式 EventCode = 2
Select
LogDate,
EndOfDay = MAX(LogDateTime),
EventCode
FROM (
Select
LogId,
LogDateTime,
LogDate = FORMAT(LogDateTime, 'dd-MMM-yyyy'),
DriverId,
EventCode
FROM
#MyLogs
WHERE EventCode = 2
) A
Group By
LogDate, EventCode …
Run Code Online (Sandbox Code Playgroud) 我仍然是查询优化的新手,我有一个存储过程,它使用游标遍历表中的每一行,并执行以下操作:
我尝试将此 Cursor 转换为 WHILE 循环,但性能下降。所以我需要帮助将其转换为SET BASED
方法而不是Procedural Based
方法
所以 Cursor 执行这个逻辑:
-- READ Current Row into Cursor Variables
FETCH NEXT FROM crAssetIgnitionOnOff INTO
@current_iVehicleMonitoringID
, @current_iAssetID
, @current_dtUTCDateTime
, @current_sptGeoLocationPoint
, @current_fLatitude
, @current_fLongitude
, @current_fAngle
, @current_fSpeedKPH
, @current_sIgnitionStatus
, @current_eEventCode
, @current_sEventCode
IF(@current_iAssetID = @prev_iAssetID)
BEGIN
---- Calculate Time Difference from previous Point
DECLARE @diffInSeconds INT
SET @diffInSeconds = DATEDIFF(SECOND, @prev_dtUTCDateTime, @current_dtUTCDateTime) …
Run Code Online (Sandbox Code Playgroud) performance sql-server optimization cursors sql-server-2012 query-performance