【问题标题】:Query Performance, Multiple "OR's" vs. Separate Statements查询性能,多个“或”与单独的语句
【发布时间】:2011-03-13 10:41:11
【问题描述】:

假设我有一个 40MM 9 位邮政编码的 Oracle 数据库表,其中每个邮政编码都包含 4 位邮政编码。我有一个包含 800 个 5 位邮政编码的列表,我需要找到所有相关的 9 位邮政编码。总共有 40K 个 5 位数的邮政编码。假设我们已经使用 B*Tree(常规)索引对 5 位邮政编码字段进行了索引。考虑到数据库性能和可扩展性,最好的方法是:

  1. 在一条语句中查询所有记录?像这样运行一次:

    SELECT * FROM ZIPCODE WHERE ZIP5 IN (:1, :2,... :800)

  2. 对每个 5 位数的邮政编码查询一次?像这样运行 800 次:

    SELECT * FROM ZIPCODE WHERE ZIP5 = :1

  3. 介于两者之间的一些批量大小?

你怎么看,为什么?如果您有思考的心情,一些 [可选] 后续想法:

  • 我们可以运行哪些测试来验证您的想法?
  • 最佳方法是否会随着数量的变化而变化(例如,如果我们将 100 个 9 位邮政编码映射到 10 个 5 位邮政编码,则查找这 10 个中的 3 个)?
  • 数据库的最佳选择与吸收查询结果的应用服务器的最佳选择不同吗?

【问题讨论】:

    标签: sql performance oracle scalability


    【解决方案1】:

    您可以选择创建外部表吗?即,

    CREATE TABLE zip5 (zip5 varchar2(5))
    ORGANIZATION EXTERNAL
    (
      TYPE ORACLE_LOADER
      DEFAULT DIRECTORY <some oracle DIRECTORY object>
      LOCATION (<yourDirectory>:'zip5 filename.txt'
    )
    

    将您的 zip5 文本文件放在您的 Oracle 目录对象指定的操作系统目录中, 然后执行:

    SELECT * FROM zipcode JOIN zip5 ON (zipcode.zip5 = zip5.zip5);
    

    与每次 ZIP5 列表更改时重新构建查询相比,这是一种更通用的解决方案。

    【讨论】:

      【解决方案2】:

      让数据库服务器决定如何处理它。即使它在内部执行 800 次查询,它仍然会更快。它只需要解析一次查询,并且只需要发送一次结果。

      因此,使用SELECT * FROM ZIPCODE WHERE ZIP5 IN (:1, :2,... :800)

      【讨论】:

      • +1 需要注意的是,一个 IN 列表最多只能包含 1000 个项目。如果你已经是 800 了,那对我来说有点太接近了。将列表粘贴到另一个表(全局临时表?)并执行 SELECT * FROM ZIPCODE WHERE ZIP5 IN (SELECT ZIP5 FROM ...)
      • +1 加里的回答。从表中选择比列表中的 800 快得多。
      猜你喜欢
      • 2011-03-25
      • 1970-01-01
      • 1970-01-01
      • 2021-09-27
      • 1970-01-01
      • 2017-11-16
      • 1970-01-01
      • 2012-06-27
      • 1970-01-01
      相关资源
      最近更新 更多