如何使用SQL Server CE表索引-是否值得为此查询执行此操作?

如何使用SQL Server CE表索引-是否值得为此查询执行此操作?,sql,indexing,sql-server-ce,Sql,Indexing,Sql Server Ce,这是一个学习过程,我最终获得了一个运行SQL Server Compact Edition的查询 我最初的问题仍然存在,那就是如何提高性能。一些人评论说,我应该尝试为我的查询编制索引,以便这就是我现在看到的 此查询将获取一个学校中属于一个权重的所有玩家,并选择其中的最高技能,并将该玩家的起始值设置为true cmd.CommandText = "UPDATE player " & "SET starter = 'TRUE' " &

这是一个学习过程,我最终获得了一个运行SQL Server Compact Edition的查询

我最初的问题仍然存在,那就是如何提高性能。一些人评论说,我应该尝试为我的查询编制索引,以便这就是我现在看到的

此查询将获取一个学校中属于一个权重的所有玩家,并选择其中的最高技能,并将该玩家的起始值设置为true

        cmd.CommandText = "UPDATE player " &
            "SET starter = 'TRUE' " &
            "WHERE NOT EXISTS" &
            "(SELECT school, weight, skill " &
            "FROM player b " &
            "WHERE b.school = player.school " &
            "AND b.weight = player.weight " &
            "AND b.skill > player.skill)"
        cmd.ExecuteNonQuery()
查询运行速度非常慢

  • 我的“玩家”表约有170000名玩家
  • 每个球员都属于4500所学校中的一所
  • 每个运动员属于14个砝码中的一个
  • 每所学校属于50个州中的一个
是否有任何方法可以索引此查询以使其运行更快?或者我能做什么,因为现在运行这个查询所花费的时间太多了

如果它有助于解释我正在使用什么,我将提供一个播放器表的图像。(未显示ID和名字)

谢谢

@这是我在程序中输入的查询

        cmd.CommandText = "update p1 " &
                    "set starter = 'TRUE' " &
                    "from player as p1 " &
                    "left outer join player as p2 " &
                    "on p1.school = p2.school " &
                    "and p1.weight = p2.weight " &
                    "and p1.playerId <> p2.playerId " &
                    "and p1.skill <= p2.skill " &
                    "where(p2.playerId Is null)"
        cmd.ExecuteNonQuery()
cmd.CommandText=“更新p1”&
“设置启动器='TRUE'”&
“从作为p1的播放器”&
“左外联球员作为p2”&
“关于p1.school=p2.school”&
“和p1.weight=p2.weight”&
“和p1.playerId p2.playerId”&

“p1.skill在这种情况下,运行sql所执行的代码有点让人困惑。我在下面重申了这一点:

UPDATE player SET starter = 'TRUE' WHERE NOT EXISTS 
(
  SELECT school, weight, skill 
    FROM player b 
   WHERE b.school = player.school 
     AND b.weight = player.weight 
     AND b.skill > player.skill
)
让我们首先看一下内部select语句。该语句本质上是从一个表“player”中请求一个包含三列(school、weight、skill)的结果表。您将该表别名为“b”。然后继续按三个方面进行筛选:b.school是否等同于player.school等等

第一个问题是,基于别名,b.school=player.school相当于player.school=player.school。对于前两个筛选器,将选择所有行-这是不必要的计算。但是,最终筛选器应始终返回false,这就是为什么查询很可能花费很长时间的原因:所有行都将是r从内部select语句返回

假设,在外部语句中,你将玩家别名为,比如,a,那么你将得到一个单独的结果,因为你现在问玩家a是否在同一个学校,是否有相同的体重,是否更好不过,在这种情况下,你要做的是将每个玩家与其他玩家进行比较:对于170000名玩家来说,这是170k^2或大约390亿次比较…这就是为什么这个查询如此缓慢的原因

有两种方法可以解决你的问题。第一种是通过编程来处理这些问题

  • 选择所有唯一的学校作为查询
  • 对于每个学校,运行类似的查询
  • 另一个是做一个聪明的sql连接。这里我使用“playerId”作为一些列,它是唯一的标识符。(希望您的表有一个。)

    通过使用内置的连接功能(3),此查询将运行得更快,并生成一个包含所有可能匹配的表(仅限同一学校和相同权重的玩家),然后根据技能进行筛选。原始结果表pre filter将比您使用的表小得多

    最后一件事:使用“notexists”非常麻烦,可能会影响您的性能

    UPDATE player c SET starter = 'TRUE' WHERE c.player IN
    (
      SELECT a.playerId 
        FROM player a INNER JOIN player b
          ON ( a.school = b.school AND a.weight = b.weight)
       WHERE a.skill > b.skill
    )
    
    (1) 注意:在某些sql实现中,内部语句中的“player”可能会被解释为外部语句中的“player”,但我不确定这是否可以保证。因此,您应该将其别名以确保

    (2) 我不是100%的,因为我没有你的桌子可以玩


    (3) SQL Server的构建通常是为了加快这方面的速度。但您必须知道如何使用它。

    在这种情况下,运行SQL所执行的代码有点让人困惑。我在下面重申了这一点:

    UPDATE player SET starter = 'TRUE' WHERE NOT EXISTS 
    (
      SELECT school, weight, skill 
        FROM player b 
       WHERE b.school = player.school 
         AND b.weight = player.weight 
         AND b.skill > player.skill
    )
    
    让我们首先看一下内部select语句。该语句本质上是从一个表“player”中请求一个包含三列(school、weight、skill)的结果表。您将该表别名为“b”。然后继续按三个方面进行筛选:b.school是否等同于player.school等等

    第一个问题是,基于别名,b.school=player.school相当于player.school=player.school。对于前两个筛选器,将选择所有行-这是不必要的计算。但是,最终筛选器应始终返回false,这就是为什么查询很可能花费很长时间的原因:所有行都将是r从内部select语句返回

    假设,在外部语句中,你将玩家别名为,比如,a,那么你将得到一个单独的结果,因为你现在问玩家a是否在同一个学校,是否有相同的体重,是否更好不过,在这种情况下,你要做的是将每个玩家与其他玩家进行比较:对于170000名玩家来说,这是170k^2或大约390亿次比较…这就是为什么这个查询如此缓慢的原因

    有两种方法可以解决你的问题。第一种是通过编程来处理这些问题

  • 选择所有唯一的学校作为查询
  • 对于每个学校,运行类似的查询
  • 另一个是做一个聪明的sql连接。这里我使用“playerId”作为一些列,它是唯一的标识符。(希望您的表有一个。)

    通过使用内置的连接功能(3),此查询将运行得更快,并生成一个包含所有可能匹配的表(仅限同一学校和相同权重的玩家),然后根据技能进行筛选。原始结果表pre filter将比您使用的表小得多

    最后一件事:使用“不存在”是非常困难的,可能会影响您的性能。试试看
    WHERE b.RowId = player.RowId
    
    update p1
    set starter = 'TRUE'
    from player as p1
    left outer join player as p2
       on p1.school = p2.school
      and p1.weight = p2.weight
      and p1.playerId <> p2.playerId
      and p1.skill <= p2.skill
    where p2.playerId is null
    
    create index player_i01 on player ( school, weight, skill, playerId )