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
Sql 慢速自连接删除查询_Sql_Performance_Join_Sql Delete_Self Join - Fatal编程技术网

Sql 慢速自连接删除查询

Sql 慢速自连接删除查询,sql,performance,join,sql-delete,self-join,Sql,Performance,Join,Sql Delete,Self Join,它比这个查询简单吗 delete a.* from matches a inner join matches b ON (a.uid = b.matcheduid) 是的,显然是这样。。。因为当匹配表非常大时,上述查询的性能非常差 匹配项约为2.2亿条记录。我希望这个删除查询将记录的大小减少到15000条左右。如何提高查询的性能?我在两列上都有索引。UID和MatchedUID是此InnoDB表中仅有的两列,它们的类型都是INT(10)unsigned。查询在我的笔记本电脑(i7处理器

它比这个查询简单吗

delete a.* from matches a
    inner join matches b ON (a.uid = b.matcheduid)
是的,显然是这样。。。因为当
匹配
表非常大时,上述查询的性能非常差


匹配项约为2.2亿条记录。我希望这个删除查询将记录的大小减少到15000条左右。如何提高查询的性能?我在两列上都有索引。UID和MatchedUID是此InnoDB表中仅有的两列,它们的类型都是INT(10)unsigned。查询在我的笔记本电脑(i7处理器)上运行了14个多小时。

运行解释选择a.*从匹配a的内部联接匹配b的(a.uid=b.matcheduid)将解释索引的存在和使用方式。

运行解释选择a.*从匹配a的内部联接匹配b的(a.uid=b.matcheduid)我想解释一下你的索引是如何存在和使用的

删除这么多记录可能需要一段时间,我认为如果你这样做的话,这是最快的。如果您不想投资更快的硬件,我建议另一种方法:

如果确实要删除2.2亿条记录,那么表中只剩下15000条记录,这大约占所有条目的99999%。为什么不呢

  • 创建一个新表
  • 只需插入所有你想保存的记录
  • 把你的旧的换成新的
  • 类似这样的方法可能会更快一些:

    /* creating the new table */
    CREATE TABLE matches_new
    SELECT a.* FROM matches a
    LEFT JOIN matches b ON (a.uid = b.matcheduid)
    WHERE ISNULL (b.matcheduid)
    
    /* renaming tables */
    RENAME TABLE matches TO matches_old;
    RENAME TABLE matches_new TO matches;
    

    在此之后,您只需检查并创建所需的索引,如果只处理15000条记录,则索引速度应该相当快。

    删除这么多记录可能需要一段时间,我认为这样做的速度与这样做的速度一样快。如果您不想投资更快的硬件,我建议另一种方法:

    如果确实要删除2.2亿条记录,那么表中只剩下15000条记录,这大约占所有条目的99999%。为什么不呢

  • 创建一个新表
  • 只需插入所有你想保存的记录
  • 把你的旧的换成新的
  • 类似这样的方法可能会更快一些:

    /* creating the new table */
    CREATE TABLE matches_new
    SELECT a.* FROM matches a
    LEFT JOIN matches b ON (a.uid = b.matcheduid)
    WHERE ISNULL (b.matcheduid)
    
    /* renaming tables */
    RENAME TABLE matches TO matches_old;
    RENAME TABLE matches_new TO matches;
    

    在此之后,您只需检查并创建所需的索引,如果只处理15000条记录,这应该是相当快的。

    我可能会在这里设置自己,但在自连接过程中执行这样的删除操作,不是吗;查询在每次删除后是否必须重新计算联接索引

    虽然它是笨拙的蛮力,你也可以考虑:

    A.创建一个临时表来存储内部连接产生的uid,然后连接到该表,然后执行删除

    B.添加一个布尔(位)类型的列,使用连接标记每个匹配项(此操作应快速),然后使用:

    DELETE * FROM matches WHERE YourBitFlagColumn = True
    

    然后删除布尔列。

    我可能会在这里设置自己被烤熟,但在自连接过程中执行这样的删除操作,不是吗;查询在每次删除后是否必须重新计算联接索引

    虽然它是笨拙的蛮力,你也可以考虑:

    A.创建一个临时表来存储内部连接产生的uid,然后连接到该表,然后执行删除

    B.添加一个布尔(位)类型的列,使用连接标记每个匹配项(此操作应快速),然后使用:

    DELETE * FROM matches WHERE YourBitFlagColumn = True
    

    然后删除布尔列。

    您可能需要批量删除。您可以通过使用公共表表达式的递归删除来执行此操作,也可以在某个批处理大小上对其进行迭代。

    您可能需要对删除进行批处理。您可以通过使用公共表表达式进行递归删除来实现这一点,也可以在某个批处理大小上对其进行迭代。

    愚蠢的想法:使用
    SELECT
    可以更快地解决问题吗?如果是这样,请创建一个包含要删除的ID的临时表,然后连接该表或在(子查询)
    中使用
    ,看看这是否更快。其他愚蠢的想法:这些列上有索引吗?是的,两列上都有索引。也许这就是删除速度慢的原因@丹-我试试你的建议。愚蠢的想法:用
    选择
    会更快解决问题吗?如果是这样,请创建一个包含要删除的ID的临时表,然后连接该表或在(子查询)
    中使用
    ,看看这是否更快。其他愚蠢的想法:这些列上有索引吗?是的,两列上都有索引。也许这就是删除速度慢的原因@丹-我试试你的建议。这几乎是不需要动脑筋的。完美的答案!查询完成后,我会通知您。希望不会花太长时间。:)@是的,嗯?我是这样想的,因为我想念森林,这很好。我去睡觉了,所以不知道花了多长时间,但这肯定是一个进步@XIV解决方案-我应该知道是删除让我慢了下来(因为索引)。检查NULL时的左外连接正是我想要的,但我想不出来。有时候很令人沮丧,对吧?这几乎是不需要动脑筋的。完美的答案!查询完成后,我会通知您。希望不会花太长时间。:)@是的,嗯?我是这样想的,因为我想念森林,这很好。我去睡觉了,所以不知道花了多长时间,但这肯定是一个进步@XIV解决方案-我应该知道是删除让我慢了下来(因为索引)。检查NULL时的左外连接正是我想要的,但我想不出来。有时会令人沮丧,对吧?这可能会起作用,但至少给出穹顶类的示例或链接会有所帮助。这可能会起作用,但至少给出穹顶类的示例或链接会有所帮助。