Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.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
优化我的Azure SQL PaaS表和/或查询以提高性能_Sql_Performance_Azure_Azure Sql Database_Azure Sql Server - Fatal编程技术网

优化我的Azure SQL PaaS表和/或查询以提高性能

优化我的Azure SQL PaaS表和/或查询以提高性能,sql,performance,azure,azure-sql-database,azure-sql-server,Sql,Performance,Azure,Azure Sql Database,Azure Sql Server,我正在设计一个具有非常特殊使用模式的桌子。 该表将以有限的通信量持续记录到日志中,每秒约25条记录,然后每晚我运行一个大型查询来提取大量数据 我的表创建脚本当前如下所示: SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO IF NOT EXISTS (select * from sysobjects where name='records' and xtype='U') CREATE TABLE [dbo].[records]( [Tr

我正在设计一个具有非常特殊使用模式的桌子。 该表将以有限的通信量持续记录到日志中,每秒约25条记录,然后每晚我运行一个大型查询来提取大量数据

我的表创建脚本当前如下所示:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

IF NOT EXISTS (select * from sysobjects where name='records' and xtype='U')
CREATE TABLE [dbo].[records](
    [TripID] varchar(255) NOT NULL,
    [RecordTimeUTC] datetime2(0) NOT NULL,
    [TimeOfDaySeconds] [int] NOT NULL,
    [T0Latitude] [float] NOT NULL,
    [T0Longitude] [float] NOT NULL,
    [T1Latitude] [float] NULL,
    [T1Longitude] [float] NULL,
    [T2Latitude] [float] NULL,
    [T2Longitude] [float] NULL,
    [T3Latitude] [float] NULL,
    [T3Longitude] [float] NULL,
    [T4Latitude] [float] NULL,
    [T4Longitude] [float] NULL,
    [T5Latitude] [float] NULL,
    [T5Longitude] [float] NULL,
    [VehicleID] [int] NULL,
    [ID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY
) ON [PRIMARY]
GO

IF NOT EXISTS (select * from sys.indexes where name='TripIDRecordTimeIndex' and object_id = OBJECT_ID('dbo.records'))
    CREATE INDEX TripIDRecordTimeIndex ON records (TripID, RecordTimeUTC desc)
GO

IF NOT EXISTS (select * from sys.indexes where name='TripIDIndex' and object_id = OBJECT_ID('dbo.records'))
    CREATE INDEX TripIDIndex ON records (TripID)
GO

IF NOT EXISTS (select * from sys.indexes where name='RecordTimeUTCIndex' and object_id = OBJECT_ID('dbo.records'))
    CREATE INDEX RecordTimeUTCIndex ON records (RecordTimeUTC desc)
GO

IF NOT EXISTS (select  * from sys.objects where name like 'UniqueConstraint2' and parent_object_id = OBJECT_ID('dbo.records'))
    ALTER TABLE [dbo].[records] ADD CONSTRAINT UniqueConstraint2 UNIQUE(VehicleID, RecordTimeUTC desc);
GO

IF NOT EXISTS (select * from sys.indexes where name='VehicleIDIndex' and object_id = OBJECT_ID('dbo.records'))
    CREATE INDEX VehicleIDIndex ON records (VehicleID)
GO
SELECT rs.* FROM (SELECT *, ROW_NUMBER() over (Partition BY TripID ORDER BY RecordTimeUTC DESC ) AS Rank FROM records where TripID in (20141000,20441000,30011022,30011021,30011008,30012029,30012028,30012027,30011007,30011019,30011018,30012026,30012025,30012024,30011017,30011016,30012023,30012022,30011015,30011014,30012021,30012020,30011013,30011012,30013000,30013001,30013019,30013009,30011011,30011010,30011009,30013008,30013007,30012010,30012009,30013005,30013004,30013003,30012014,30012019,30013021,30013020,30011006,30011004,30012018,30012017,30012016,30013006,30011003,30011002,30012015,30012013,30013013,30013002,30011001,30011000,30011020,30012012,30012011,30011005,30011030,30012001,30012008,30012007,30011029,30011028,30012006,30012005,30011031,30011027,30012004,30012003,30011026,30011025,30011024,30012002,30012000,30012031,30011023,30012030,30015005,30016006,30016013,30016012,30014020,30014019,30014018,30016011,30016010,30014017,30014016,30016009,30016008,30014015,30014013,30014012,30016005,30016004,30016003,30014010,30014009,30016002,30016001,30014008,30014007,30016000,30016007,30014006,30014005,30014004,30014003,30014002,30014001,30014000,30014023,30014014,30015012,30015004,30015003,30013018,30013017,30015002,30015001,30013016,30013015,30013014,30015000,30015013,30015011,30013012,30013011,30015010,30015009,30013010,30014011,30015008,30015007,30014022,30014021,30015006,33651001,33661006)) rs WHERE Rank <= 690
 UNION 
SELECT rs.* FROM (SELECT *, ROW_NUMBER() over (Partition BY TripID ORDER BY RecordTimeUTC DESC ) AS Rank FROM records where TripID in (20431003,20431002,20431001,20432003,20432002,20432001,30221001,33861002,33861003)) rs WHERE Rank <= 855
 UNION 
SELECT rs.* FROM (SELECT *, ROW_NUMBER() over (Partition BY TripID ORDER BY RecordTimeUTC DESC ) AS Rank FROM records where TripID in (20171029,20171030,20002002,26122001)) rs WHERE Rank <= 45
 UNION 
...
目前,我的表中有大约6000万条记录,其大小不到50GB

提取数据的查询非常耗时。目前需要一个多小时。我不确定是我的表设计还是查询设计是根本原因,尽管可能两者都是

我需要为我指定的一组TripID中的每个TripID提取最新X数量的项目。大约有10k个不同的ID,我通常想查询其中的一半。X在它们之间也有所不同,因此我目前查询的最佳方式是生成一个看起来有点像这样的脚本:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

IF NOT EXISTS (select * from sysobjects where name='records' and xtype='U')
CREATE TABLE [dbo].[records](
    [TripID] varchar(255) NOT NULL,
    [RecordTimeUTC] datetime2(0) NOT NULL,
    [TimeOfDaySeconds] [int] NOT NULL,
    [T0Latitude] [float] NOT NULL,
    [T0Longitude] [float] NOT NULL,
    [T1Latitude] [float] NULL,
    [T1Longitude] [float] NULL,
    [T2Latitude] [float] NULL,
    [T2Longitude] [float] NULL,
    [T3Latitude] [float] NULL,
    [T3Longitude] [float] NULL,
    [T4Latitude] [float] NULL,
    [T4Longitude] [float] NULL,
    [T5Latitude] [float] NULL,
    [T5Longitude] [float] NULL,
    [VehicleID] [int] NULL,
    [ID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY
) ON [PRIMARY]
GO

IF NOT EXISTS (select * from sys.indexes where name='TripIDRecordTimeIndex' and object_id = OBJECT_ID('dbo.records'))
    CREATE INDEX TripIDRecordTimeIndex ON records (TripID, RecordTimeUTC desc)
GO

IF NOT EXISTS (select * from sys.indexes where name='TripIDIndex' and object_id = OBJECT_ID('dbo.records'))
    CREATE INDEX TripIDIndex ON records (TripID)
GO

IF NOT EXISTS (select * from sys.indexes where name='RecordTimeUTCIndex' and object_id = OBJECT_ID('dbo.records'))
    CREATE INDEX RecordTimeUTCIndex ON records (RecordTimeUTC desc)
GO

IF NOT EXISTS (select  * from sys.objects where name like 'UniqueConstraint2' and parent_object_id = OBJECT_ID('dbo.records'))
    ALTER TABLE [dbo].[records] ADD CONSTRAINT UniqueConstraint2 UNIQUE(VehicleID, RecordTimeUTC desc);
GO

IF NOT EXISTS (select * from sys.indexes where name='VehicleIDIndex' and object_id = OBJECT_ID('dbo.records'))
    CREATE INDEX VehicleIDIndex ON records (VehicleID)
GO
SELECT rs.* FROM (SELECT *, ROW_NUMBER() over (Partition BY TripID ORDER BY RecordTimeUTC DESC ) AS Rank FROM records where TripID in (20141000,20441000,30011022,30011021,30011008,30012029,30012028,30012027,30011007,30011019,30011018,30012026,30012025,30012024,30011017,30011016,30012023,30012022,30011015,30011014,30012021,30012020,30011013,30011012,30013000,30013001,30013019,30013009,30011011,30011010,30011009,30013008,30013007,30012010,30012009,30013005,30013004,30013003,30012014,30012019,30013021,30013020,30011006,30011004,30012018,30012017,30012016,30013006,30011003,30011002,30012015,30012013,30013013,30013002,30011001,30011000,30011020,30012012,30012011,30011005,30011030,30012001,30012008,30012007,30011029,30011028,30012006,30012005,30011031,30011027,30012004,30012003,30011026,30011025,30011024,30012002,30012000,30012031,30011023,30012030,30015005,30016006,30016013,30016012,30014020,30014019,30014018,30016011,30016010,30014017,30014016,30016009,30016008,30014015,30014013,30014012,30016005,30016004,30016003,30014010,30014009,30016002,30016001,30014008,30014007,30016000,30016007,30014006,30014005,30014004,30014003,30014002,30014001,30014000,30014023,30014014,30015012,30015004,30015003,30013018,30013017,30015002,30015001,30013016,30013015,30013014,30015000,30015013,30015011,30013012,30013011,30015010,30015009,30013010,30014011,30015008,30015007,30014022,30014021,30015006,33651001,33661006)) rs WHERE Rank <= 690
 UNION 
SELECT rs.* FROM (SELECT *, ROW_NUMBER() over (Partition BY TripID ORDER BY RecordTimeUTC DESC ) AS Rank FROM records where TripID in (20431003,20431002,20431001,20432003,20432002,20432001,30221001,33861002,33861003)) rs WHERE Rank <= 855
 UNION 
SELECT rs.* FROM (SELECT *, ROW_NUMBER() over (Partition BY TripID ORDER BY RecordTimeUTC DESC ) AS Rank FROM records where TripID in (20171029,20171030,20002002,26122001)) rs WHERE Rank <= 45
 UNION 
...
上述查询返回第一个列表中每个行程的690个实例,第二个列表中每个行程的855个实例,第三个列表中的45个实例,依此类推。查询比这个大得多-这只是它的一个片段。我总共提取了1000-1500万行

如前所述,我的表现很糟糕。是云的东西吗?这是设计吗?我应该使用聚集索引吗?为TripID试过,但那更糟。我可以改进我的查询吗?为实例的每个ID提取相同数量的实例,然后过滤

我注意到我有两个额外的索引,它们可能不会在我的查询中使用。我只是尝试添加更多,因为插入性能不是问题。计划是在我的查询中使用TripIDRecordTimeIndex

即使将Azure SQL中的数据计划扩展到S7 800 DPU,我也无法快速运行。任何反馈都将不胜感激

编辑:我最近将TripID从int更改为varchar255-这会破坏我的性能吗

Edit2:执行计划:

Edit3:我发现在我查询的TripID周围添加引号极大地提高了性能

编辑4:我按照GameisWar的建议添加了索引,区别是白天和黑夜!非常感谢。附上新的执行计划

我将创建一个如下所示的索引

create index nci_sometst on table (tripid,recorddatetime)
include(<remaining columsn you are selecting>)
上面的查询有助于获取tripID中的部分记录,但如果内部查询的结果集很大,则使用派生表计算秩可能没有多大帮助

我可能会将其放入一个临时表中,并在秩上创建一个索引,因此这对其他联合查询也很有帮助

还查看了您的执行计划,我可以看到您多次扫描同一个表,每次都读取许多行


即使没有数据类型转换警告,您的查询也不会有效地使用任何索引

这是一个非常广泛的问题。对于初学者来说,您是否看过查询的SQL执行计划?这是一个我所知甚少的领域。我在问题的底部为执行计划的子集添加了一份执行计划副本。我意识到这是一个广泛的问题,但原因是我不知道去哪里找。感谢您的反馈。计划的图片不是查询计划。您需要链接到该文件:在检查执行计划时,一般的想法是查看查询中占用时间最多的步骤。在您的例子中,有两个聚集索引扫描。由于您的表有6000万行,这将造成伤害。您可以在这里阅读有关索引查找与扫描的内容:您正在扫描整个表,然后稍后进行筛选。表现只会越来越差。在检索数据之前,您需要能够过滤数据。但是,您是说需求需要访问一半的数据。这总是会导致扫描。这是一个设计问题,而不是云问题。这绝对是个好办法!创建花了一段时间,但一旦出现,所有查询几乎都是即时的!非常感谢。PS:我只在每个TripID上查询一次,所以我认为临时表不会有帮助。很高兴它帮助了你,如果你能提供更多细节,将来也会有帮助。寻求性能帮助的问题应该包括涉及的表的DDL、DML以及测试数据。如果你的测试数据很大,尝试为表编写架构和统计信息脚本右键单击数据库->生成脚本->选择特定的数据库对象->在下一个屏幕中选择高级并选择脚本统计信息并将其粘贴到问题中。使用此信息,任何人都可以复制您面临的相同问题。否则,回答您的问题会变得非常困难。粘贴服务器版本也有帮助