Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.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查询,以使其执行速度更快?_Sql_Sql Server_Tsql_Sql Server 2005 - Fatal编程技术网

是否可以使用多个内部联接重写此SQL查询,以使其执行速度更快?

是否可以使用多个内部联接重写此SQL查询,以使其执行速度更快?,sql,sql-server,tsql,sql-server-2005,Sql,Sql Server,Tsql,Sql Server 2005,我有一张20万行的桌子。我已经创建了一个视图,在此视图中,我将根据不同的标准从该表中删除数据片段,这些标准符合我对构成重复记录的内容的定义。我在下面有这样做的代码,我想知道是否有人可以建议一种更快/更有效的方法来编写这个查询。目前执行这个查询大约需要20秒,但我希望执行这个查询最多需要几秒钟。我正在使用SQLServer2005。我的SQL知识是非常初学者,我感谢任何帮助 WITH dsm_hardware_basic_cte AS ( SELECT TOP 100 PERCENT

我有一张20万行的桌子。我已经创建了一个视图,在此视图中,我将根据不同的标准从该表中删除数据片段,这些标准符合我对构成重复记录的内容的定义。我在下面有这样做的代码,我想知道是否有人可以建议一种更快/更有效的方法来编写这个查询。目前执行这个查询大约需要20秒,但我希望执行这个查询最多需要几秒钟。我正在使用SQLServer2005。我的SQL知识是非常初学者,我感谢任何帮助

WITH dsm_hardware_basic_cte AS
(
 SELECT    TOP 100 PERCENT
           dbo.dsm_hardware_basic.[UUID]
          ,dbo.dsm_hardware_basic.[Name]
          ,dbo.dsm_hardware_basic.[LastAgentExecution]
          ,dbo.dsm_hardware_basic.[MaxUserRegistration]
          ,REPLACE(RIGHT([MaxUserRegistration], CHARINDEX('/', REVERSE([MaxUserRegistration])) - 1),'_ADMIN','') AS [MaxUserUsername]
          ,dbo.dsm_hardware_basic.[LastUserRegistration]
          ,REPLACE(RIGHT([LastUserRegistration], CHARINDEX('/', REVERSE([LastUserRegistration])) - 1),'_ADMIN','') AS [LastUserUsername]
          ,dbo.dsm_hardware_basic.[IPAddress]
          ,dbo.dsm_hardware_basic.[HostName]
          ,dbo.dsm_hardware_basic.[MACAddress]
 FROM      dbo.dsm_hardware_basic
)

SELECT     TOP 100 PERCENT
           dsm_hardware_basic_cte.[UUID]
          ,dsm_hardware_basic_cte.[Name]
          ,dsm_hardware_basic_cte.[LastAgentExecution]
          ,dsm_hardware_basic_cte.[MaxUserRegistration]
          ,dsm_hardware_basic_cte.[LastUserRegistration]
          ,dsm_hardware_basic_cte.[IPAddress]
          ,dsm_hardware_basic_cte.[HostName]
          ,dsm_hardware_basic_cte.[MACAddress]
FROM       dsm_hardware_basic_cte
           INNER JOIN
           (
            SELECT    [UUID]
                     ,ROW_NUMBER() OVER (PARTITION BY [Name], [MACAddress] ORDER BY [LastAgentExecution] DESC) AS [NameMACRowNum]
            FROM      dsm_hardware_basic_cte
           ) AS duplicate_NameMAC_filtered
             ON duplicate_NameMAC_filtered.[UUID] = dsm_hardware_basic_cte.[UUID]
            AND duplicate_NameMAC_filtered.[NameMACRowNum] = 1
           INNER JOIN
           (
            SELECT    [UUID]
                     ,ROW_NUMBER() OVER (PARTITION BY [Name], [HostName] ORDER BY [LastAgentExecution] DESC) AS [NameHostNameRowNum]
            FROM      dsm_hardware_basic_cte
           ) AS duplicate_NameHostName_filtered
             ON duplicate_NameHostName_filtered.[UUID] = dsm_hardware_basic_cte.[UUID]
            AND duplicate_NameHostName_filtered.[NameHostNameRowNum] = 1
           INNER JOIN
           (
            SELECT    [UUID]
                     ,ROW_NUMBER() OVER (PARTITION BY [HostName], [MACAddress] ORDER BY [LastAgentExecution] DESC) AS [HostNameMACRowNum]
            FROM      dsm_hardware_basic_cte
           ) AS duplicate_HostNameMAC_filtered
             ON duplicate_HostNameMAC_filtered.[UUID] = dsm_hardware_basic_cte.[UUID]
            AND duplicate_HostNameMAC_filtered.[HostNameMACRowNum] = 1
           INNER JOIN
           (
            SELECT    [UUID]
                     ,ROW_NUMBER() OVER (PARTITION BY [HostName], [IPAddress] ORDER BY [LastAgentExecution] DESC) AS [HostNameIPAddressRowNum]
            FROM      dsm_hardware_basic_cte
           ) AS duplicate_HostNameIPAddress_filtered
             ON duplicate_HostNameIPAddress_filtered.[UUID] = dsm_hardware_basic_cte.[UUID]
            AND duplicate_HostNameIPAddress_filtered.[HostNameIPAddressRowNum] = 1
           INNER JOIN
           (
            SELECT    [UUID]
                     ,ROW_NUMBER() OVER (PARTITION BY [Name], [MaxUserUsername] ORDER BY [LastAgentExecution] DESC) AS [NameMaxUserRowNum]
            FROM      dsm_hardware_basic_cte
           ) AS duplicate_NameMaxUser_filtered
             ON duplicate_NameMaxUser_filtered.[UUID] = dsm_hardware_basic_cte.[UUID]
            AND duplicate_NameMaxUser_filtered.[NameMaxUserRowNum] = 1
           INNER JOIN
           (
            SELECT    [UUID]
                     ,ROW_NUMBER() OVER (PARTITION BY [Name], [LastUserUsername] ORDER BY [LastAgentExecution] DESC) AS [NameLastUserRowNum]
            FROM      dsm_hardware_basic_cte
           ) AS duplicate_NameLastUser_filtered
             ON duplicate_NameLastUser_filtered.[UUID] = dsm_hardware_basic_cte.[UUID]
            AND duplicate_NameLastUser_filtered.[NameLastUserRowNum] = 1

根据您的查询计划,按LastAgentExecution排序需要19%的时间。首先在此列上创建索引


但是,如果我是你,我会改变使用“ROW_NUMBER()OVER(PARTITION BY[Name],[MACAddress]ORDER BY[LastAgentExecution]DESC)”类型语法的习惯,因为它似乎不是非常有效的而不是内部联接,尝试用这样的“Exists”子句替换它们

WHERE      EXISTS           
           ((SELECT [UUID],[NameMACRowNum]
                FROM
                        (SELECT    [UUID]
                                 ,ROW_NUMBER() OVER (PARTITION BY [Name], [MACAddress] ORDER BY [LastAgentExecution] DESC) AS [NameMACRowNum]
                        FROM      dsm_hardware_basic_cte) AS duplicate_NameMAC_filtered
            WHERE duplicate_NameMAC_filtered.[UUID] = dsm_hardware_basic_cte.[UUID]
            AND duplicate_NameMAC_filtered.[NameMACRowNum] = 1)

不确定它是否应该存在,但一旦其余部分正常工作,就可以很容易地进行更改。

我不知道您需要什么,但我会尝试重新编写查询:

WITH dsm_hardware_basic_cte AS (
 SELECT
    d.[UUID]
    ,d.[Name]
    ,d.[LastAgentExecution]
    ,d.[MaxUserRegistration]
    ,REPLACE(RIGHT([MaxUserRegistration], CHARINDEX('/', REVERSE([MaxUserRegistration])) - 1),'_ADMIN','') AS [MaxUserUsername]
    ,d.[LastUserRegistration]
    ,REPLACE(RIGHT([LastUserRegistration], CHARINDEX('/', REVERSE([LastUserRegistration])) - 1),'_ADMIN','') AS [LastUserUsername]
    ,d.[IPAddress]
    ,d.[HostName]
    ,d.[MACAddress]
    ,ROW_NUMBER() OVER (PARTITION BY [Name], [MACAddress] ORDER BY [LastAgentExecution] DESC) AS [NameMACRowNum]
    ,ROW_NUMBER() OVER (PARTITION BY [Name], [HostName] ORDER BY [LastAgentExecution] DESC) AS [NameHostNameRowNum]
    ,ROW_NUMBER() OVER (PARTITION BY [HostName], [MACAddress] ORDER BY [LastAgentExecution] DESC) AS [HostNameMACRowNum]
    ,ROW_NUMBER() OVER (PARTITION BY [HostName], [IPAddress] ORDER BY [LastAgentExecution] DESC) AS [HostNameIPAddressRowNum]
    ,ROW_NUMBER() OVER (PARTITION BY [Name], [MaxUserUsername] ORDER BY [LastAgentExecution] DESC) AS [NameMaxUserRowNum]
    ,ROW_NUMBER() OVER (PARTITION BY [Name], [LastUserUsername] ORDER BY [LastAgentExecution] DESC) AS [NameLastUserRowNum]
 FROM      dbo.dsm_hardware_basic as d
)

SELECT
    c.[UUID]
    ,c.[Name]
    ,c.[LastAgentExecution]
    ,c.[MaxUserRegistration]
    ,c.[LastUserRegistration]
    ,c.[IPAddress]
    ,c.[HostName]
    ,c.[MACAddress]
FROM       dsm_hardware_basic_cte as c
WHERE
    c.[NameMACRowNum] = 1
    or c.[NameHostNameRowNum] = 1
    or c.[HostNameMACRowNum] = 1
    or [HostNameIPAddressRowNum] = 1
    or [NameMaxUserRowNum] = 1
    or [NameLastUserRowNum] = 1
我认为你的查询和我的查询在逻辑上是等价的。优化器可能足够聪明,可以将您的查询简化为我的查询,但请旋转一下,看看!几点注意:

  • 我使用表别名是为了让它更具可读性(在我看来)
  • 我从您的select中删除了“top 100%”条款。这是不需要的;这是一种典型的黑客行为,人们将其放置在适当的位置,以便在视图中执行orderby操作,从而获得“有序视图”。不要那样做。:)
    因为您使用的是SQL Server,所以第一步是查看SSMS中的实际查询计划。它是否“暗示”任何指数?查询计划在哪里显示了大部分时间被占用的位置?这个查询多久执行一次?我还不太了解查询计划。我一直在自学。今天早些时候,我确实为一个查询捕获了一个执行计划,我认为这大约需要13或14秒。您可以在这里找到它:这个查询是我所有其他查询的基础。在任何连接列表中,它总是第一个,并且经常执行。根据您提供的代码,您需要的所有列都来自“dsm_hardare_basic_cte”,对吗?下面的所有其他内部联接基本上都是为了过滤记录吗?如何在列上创建索引?此外,我还看到有人在其他问题/答案中提到为列编制索引,我想知道您是否可以简要解释为什么为列编制索引会使查询运行得更快?此外,我不确定除了视图中的行数函数之外,我还能使用什么。我编写了一个使用临时表的解决方案,这个解决方案非常快,但后来发现我不能在视图中使用临时表。实际上,我在这里找到了一个关于索引的极好解释:对代码进行了一些修改,这与我的完整查询的工作方式有更多关系,我能够让它工作,而且速度更快。谢谢