【问题标题】:SQL need most efficient way to select items list with sublists?SQL需要最有效的方法来选择带有子列表的项目列表吗?
【发布时间】:2010-01-20 20:55:57
【问题描述】:

让我们看一个非常简单的例子,有 3 个表:

  • dbo.Person(PersonId, Name, Surname)
  • dbo.Pet(PetId, Name, Breed)
  • dbo.PersonPet(PersonPetId, PersonId, PetId)

如果人有任何宠物,则需要选择所有带宠物的人......例如。在最终的应用程序中,它应该看起来像:

什么是最有效的方法:

  1. 选择所有人,然后在数据访问层用单独的选择填充每个人的宠物列表?
  2. 在 sql 级别使用连接,然后在数据访问层过滤所有重复的人,只将一个添加到结果列表中,而从另一个填充宠物列表?
  3. 还有其他想法吗?

【问题讨论】:

    标签: sql


    【解决方案1】:

    最有效的方法是一次全选:

    select p.*, pt.*
    from Person p
    left outer join PersonPet pp on p.PersonId = pp.PersonId
    left outer join Pet pt on pp.PetId = pt.PetId
    

    【讨论】:

      【解决方案2】:

      如果有人有任何宠物,则需要选择所有带宠物的人...

      用途:

         SELECT per.name,
                per.surname,
                pt.name
           FROM dbo.PERSON per
      LEFT JOIN dbo.PERSONPET perpet ON perpet.personid = per.personid
           JOIN dbo.PETS pt ON pt.petid = perpet.petid
      

      【讨论】:

        【解决方案3】:

        我个人会将其作为 sql server 上的存储过程来执行。但是,无论您采用哪种方式,出于显示目的,您都必须过滤掉重复的姓名和姓氏。

        【讨论】:

          【解决方案4】:

          检索记录所花费的大部分时间都用于设置和取消对数据库的查询。在查询中使用多少数据或多少表并没有太大区别。使用单个查询来获取所有数据会更有效率。如果您的数据访问层分别获取每个数据,您的速度会很差。绝对使用连接。

          【讨论】:

          • 这并不完全正确。如果您有一个包含数百万行但没有索引的表怎么办?设置/拆卸时间会比检索时间快吗?
          【解决方案5】:

          如果您的客户端和后端支持多个结果集,您还可以执行类似的操作(假设是 MSSQL)

          Create Proc usp_GetPeopleAndPets 
          AS
          BEGIN
              SELECT PersonId, Name, Surname
              FROM 
              dbo.Person p;
          
              SELECT 
                  pp.PersonID,
                  p.PetId, p.Name, p.Breed
              FROM
              dbo.PersonPet pp
              INNER JOIN dbo.Pet p
              ON pp.PetId = p.PetId
              Order BY pp.PersonId
          END
          

          数据检索时间大致相当于一次访问数据库。一些客户支持结果之间的关系,这允许您执行类似的操作 Person.GetPets() 或 Pet.GetPerson()

          这种方法的主要优点是,如果您与人一起工作,您不必担心“过滤[ing]所有重复的人[s]”

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-01-05
            • 2011-07-26
            • 2017-02-03
            • 2021-10-26
            • 1970-01-01
            • 2018-08-15
            • 1970-01-01
            相关资源
            最近更新 更多