【问题标题】:Running a New Sql Query VS. Looping through similar dataset - What is more efficient?运行新的 Sql 查询 VS。循环遍历类似的数据集 - 什么更有效?
【发布时间】:2018-04-05 13:28:11
【问题描述】:

我想遍历一个数据集并查看其中是否有任何重复项。我想知道哪种方式对服务器更有效。运行数据集并向数据库发送新查询,或者使用第二个嵌套 for 循环运行数据集。

我认为代码示例会让它更容易理解。

SELECT * FROM contacts;

假设这个查询产生一个数组:

[0] {id: 1, firstname: 'John', lastname: 'Smith'}
[1] {id: 2, firstname: 'Michael', lastname:'Jones'}
...
[99] {id: 100, firstname: 'Jerry', lastname:'Brown'}

并保存到一个php数组中:

$data

现在假设我要遍历$data 中的每个联系人,然后查看是否有任何名字和姓氏相同的联系人。 哪种方法效率更高?

1:

for($i = 0 ; $i < sizeof($data) ; $i++){
    #query db:
    $newQuery = SELECT * FROM Contacts WHERE firstname=$data[$i]['firstname'] AND lastname=$data[$i]['lastname'];
    if(sizeof($newQuery > 1)){
         #log contacts.
    }
}

2:

for($i = 0 ; $i < sizeof($data) ; $i++){
    for($j = $i+1; $j < sizeof($data); $i++){
        if($data[$i]['firstname'] === $data[$j]['firstname'] && $data[$i]['lastname'] === $data[$j]['lastname']){
            #log contacts;
        }
    }
}

当然,如果我完全错了,并且有更好的方法可以一起完成,我会很乐意学习!

【问题讨论】:

  • 两者都不是。 Select firstName, lastName, count(*) from contacts group by firstName, LastName having having count(*) &gt; 1在需要的时候获取你需要的数据;如果您需要更多数据,例如 ID 或其他数据;根据名字/姓氏运行第二个查询以仅获取这些记录。基于数据库集的处理将比几乎任何人可以编写的都要快。
  • 你好,不知道你到底想要什么,但你绝对应该构建一个请求并将所有条件都放在里面......
  • @xQbert 好的,我明白了。我没有想到。这要好得多。但是我想补充一点:如果我不想检查总重复项,但名称相似,该怎么办。
  • 将 soundex() 用于类似模式匹配的声音 dev.mysql.com/doc/refman/5.7/en/… 还有其他模式匹配,soundex() 只是一个示例。 Jaro-Winkler 模糊逻辑匹配是另一个。见:stackoverflow.com/questions/48406993/…
  • 您碰巧在美好的一天赶上了我 :P 您可能需要调整您的问题以在匹配中包含“相似”名称。但那些变得棘手。一旦你沿着这条路走下去,误报和可能的错误结果/匹配的机会就会增加。 1/2 的战斗是知道要寻找什么。希望这能让您走上一条更有成效的道路。

标签: php mysql sql arrays database


【解决方案1】:

最有效的方法是让数据库完成工作。这是一般规则。数据库优化器比遍历数组有更多的选择。数据库服务器通常比运行应用程序的节点更强大。 而且,与只返回您想要的结果相比,传回所有数据可能(相对)昂贵。 (也就是说,有例外,但很少见。)

如果你想要名称对,那么你可以这样做:

select firstname, lastname, count(*) as cnt
from contacts
group by firstname, lastname
having cnt > 1;

如果您想要重复的原始行,那么我会推荐exists

select c.*
from contacts c
where exists (select 1
              from contacts c2
              where c2.firstname = c.firstname and c2.lastname = c.lastname and
                    c2.id <> c.id
             );

对于此查询,您需要在contacts(lastname, firstname) 上建立索引。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多