Database 版 (精华区)

发信人: wodeji (西西), 信区: Database
标  题: [转载] PowerBuilder 开 发 系 列 谈 (18) 
发信站: 紫 丁 香 (Tue Sep 29 17:52:12 1998), 站内信件

【 以下文字转载自 Programming 讨论区 】
【 原文由 two 所发表 】


        我 们 使 用PowerBuilder 编 程 时 总 是 会 大 量 的 用 到 数 据 库 的 查 询 语 句, 对 于 一
 条 复 杂 的 查 询 语 句 来 说, 对 相 同 的 查 询 条 件 的 实 现 一 般 总 可 以 有 多 种 不 同 的
 表 达 方 法, 而 不 同 的 表 达 会 使 数 据 库 的 响 应 速 度 大 相 径 庭。 据 统 计, 约 有90%
 性 能 问 题 是 由 于 应 用 开 发 的 程 序 员 或 用 户 使 用 了 不 恰 当 的 查 询 语 句 而 使 系 统
 的 响 应 速 度 减 慢, 因 此 提 高 书 写SQL 语 句 的 质 量 对 软 件 性 能 的 提 高 有 很 大 关
 系, 然 而 查 询 语 句 的 好 坏 往 往 是 同 实 际 运 行 系 统 的 数 据 库 结 构、 记 录 的 数 量
 等 具 体 情 况 有 关 的, 我 们 无 法 只 用 几 条 简 单 的 普 遍 适 用 的 规 律 来 总 结 应 当 怎
 样 优 化 查 询 语 句, 以 得 到 更 高 的 性 能。 不 过 我 们 首 先 应 当 对 数 据 库 管 理 系 统
 最 基 本 的 工 作 规 律 有 一 些 了 解, 这 样 才 能 使 我 们 在 对 查 询 进 行 时 优 化 有 所 根
 据。 

        由 于SQL 语 言 是 面 向 结 果 而 不 是 面 向 过 程 的 查 询 语 言, 所 以 一 般 支 持SQL
 语 言 的 大 型 关 系 型 数 据 库 都 需 要 使 用 一 个 基 于 成 本 的 优 化 器, 为 一 个 即 时 查
 询 提 供 一 个 最 佳 的 执 行 策 略。 对 于 优 化 器, 输 入 是 一 条 查 询 语 句, 输 出 是 一
 个 执 行 策 略。 这 个 执 行 策 略 是 执 行 这 个 查 询 所 需 要 的 一 系 列 步 骤。 数 据 库 的
 反 应 速 度 经 常 就 体 现 在 这 一 个 优 化 算 法 上。 不 同 的 查 询 策 略 和 查 询 步 骤 可 使
 得 服 务 器 的 反 应 不 同, 因 此 采 用 适 当 的 查 询 策 略 可 使 得 系 统 性 能 大 大 的 提
 高。 

        优 化 器 的 优 化 是 基 于 用 户 对 所 查 询 表 的 内 容 和 其 他 一 些 服 务 器 的 有 关 因
 素 如Cache 大 小、Cache 策 略、I/O 大 小 等。 一 般 来 说 硬 盘 访 问 是 成 本 最 高 的 操
 作, 因 此 对 用 户 来 讲, 使 优 化 器 能 对 字 段 的 索 引 进 行 操 作 是 优 化 查 询 的 关
 键。 

        SQL 查 询 语 句 都 可 以 有 很 多 种 执 行 策 略, 优 化 器 将 估 计 出 全 部 的 执 行 方 法
 中 所 需 时 间 最 少 的 也 就 是 所 谓 成 本 最 低 的 那 一 种 方 法。 一 般 来 讲, 最 为 重 要
 的 选 择 就 是 使 用 什 么 索 引 和 采 用 何 种 表 的 连 接 手 段, 而 所 有 优 化 的 进 行 都 是
 基 于 用 户 所 使 用 的 查 询 语 句 中 的where 子 句。 

        优 化 器 对where 子 句 中 的 优 化 分 为 以 下 几 类: 
        搜 索 参 数(searchargument) 

        搜 索 参 数 的 核 心 就 是 数 据 库 能 否 使 用 表 中 字 段 的 索 引 来 查 询 数 据, 而 不
 必 直 接 查 询 记 录 中 的 数 据。 如 带 有=,<,>,>=,<= 等 操 作 符 的 条 件 系 统 就 可 以 直 接
 使 用 索 引。 

        如 下 列 条 件 是 搜 索 参 数: 

 id = " T0001”
 salary  >  30000
 a = 1 and c = 7
 而下列则不是搜索参数:
 salary = commission
 dept != 10
 salary *12  >=  30000
 a = 1 or c = 7
 当然优化器有时可以将非搜索参数转化为搜索参数,如:
 SELECT  name FROM employee   WHERE  salary   BETWEEN   $10000  AND   $15000
 SELECT  name  FROM employee   WHERE  salary  >=  $10000   AND   salary  <=  $15000
 SELECT  name  FROM  employee  WHERE  name like "a%"
 SELECT  name  FROM  employee  WHERE  name >= "a"  AND   name<= "b"
 SELECT  name  FROM  employee  WHERE  salary  >  $3000 * 12
 SELECT  name  FROM  employee  WHERE  salary  >  $36000

        因 此 我 们 在 查 询 中 应 当 提 供 能 一 些 冗 余 的 搜 索 参 数, 使 优 化 器 有 更 多 的
 选 择 余 地, 如title 和titleauthor 两 张 表 是 一 对 多 的 关 系, 同 样 的 查 询 条 件 我 们 有 以
 下 三 种 表 现 方 法: 

 SELECT  title_id, title   FROM  titles,  titleauthor
 WHERE  title.title_id = titleauthor.title_id
 AND  titleauthor.title_id = 'T81002'
 SELECT  title_id, title   FROM  titles,  titleauthor
 WHERE  title.title_id = titleauthor.title_id
 AND  title.title_id = 'T81002'
 SELECT  title_id, title   FROM  titles,  titleauthor
 WHERE  title.title_id = titleauthor.title_id
 AND  title.title_id = 'T81002'
 AND  titleauthor.title_id  = 'T81002'

        显 然 三 种 方 法 一 种 比 一 种 要 好, 因 为 后 者 为 优 化 器 提 供 了 更 多 的 选 择 机
 会。 

 连 接 条 件 

        接 连 时 优 化 器 将 所 有 连 接 的 方 法 全 部 列 举 出 来, 计 算 每 一 种 连 接 的 成 本,
 选 择 成 本 最 低 的 一 种。 如 连 接 时 用 到 的 数 据 无 法 获 得, 一 般 系 统 会 使 用 平 均
 密 度 作 为 依 据, 估 算 可 能 的 命 中 率。 ' 或' 运 算 条 件 

        当 查 询 语 句 中 有IN 这 样 的 关 键 词 时, 优 化 器 将 转 化 其 中 的 内 容 以OR 并 列
 条 件。 例 如: 

 SELECT * FROM author
 WHERE au_lname in ('Berry','Densham')
 将转化为:
 SELECT * FROM author
 WHERE au_lname = 'Berry' or au_lname = 'Densham'

        数 据 库 管 理 系 统 将 对 每 一 个OR 从 句 进 行 查 询, 将 所 有 的 结 果 合 并 后 去 除
 重 复 项 作 为 最 终 结 果。 

        基 于 对 上 述 数 据 库 优 化 器 的 了 解, 为 确 保 对 我 们 将 要 执 行 的 查 询 语 句 得
 以 进 行 准 确 的 优 化, 我 们 应 注 意 以 下 几 点: 

        1. 避 免 使 用 不 兼 容 的 数 据 类 型。 例 如float 和int,char 和varchar,binary 和varbinary 是
 不 兼 容 的。 数 据 类 型 的 不 兼 容 可 能 使 得 优 化 器 无 法 执 行 一 些 本 来 可 以 进 行 的
 优 化 操 作。 例 如: 

 SELECT  name  FROM  employee
 WHERE  salary  >  60000

        在 这 条 语 句 中, 如salary 字 段 是money 型 的, 则 优 化 器 很 难 对 其 进 行 优 化, 因
 为60000 是 个 整 型 数。 我 们 应 当 在 编 程 是 使 用 一 个 函 数 将 整 型 数 转 化 成 为 钱 币
 型 的 数, 而 不 要 等 到 运 行 时 转 化。 

        2. 如 果 在 一 个 存 储 过 程 或 触 发 器 中, 有 表 达 式 的 值 在 编 译 时 无 法 得 到, 优
 化 器 就 只 能 使 用 它 的 平 均 密 度 来 估 计 命 中 的 记 录 数。 例 如: 

 DECLARE  @value  money
 SELECT  name
 FROM     employee
 WHERE  salary  =  @value

        这 样 的 命 令 是 可 优 化 的。 只 是 由 于@value 的 值 在 执 行 前 不 知 道, 它 只 能 使
 用 其 平 均 密 度, 来 估 计 这 条 命 令 将 要 命 中 的 记 录 数。 

        3. 避 免 对 搜 索 参 数 使 用 其 他 数 学 操 作 符。 如 要 将 

 SELECT  name  FROM  employee
 WHERE  SUBSTRING(id, 1, 1) = 'B'
 SELECT  name  FROM  emplyee
 WHERE  salary  * 12  >  30000
 写成为:
 SELECT  name  FROM  employee
 WHERE  id   like 'B%'
 SELECT  name  FROM  emplyee
 WHERE  salary   >  3000

        4. 避 免 使 用!= 或<> 等 这 样 的 操 作 符, 因 为 这 会 使 系 统 无 法 使 用 索 引, 而 只
 能 直 接 搜 索 表 中 的 数 据。 例 如: 
        SELECT id FROM employee 
        WHERE id != 'B%' 

        优 化 器 将 无 法 通 过 索 引 来 确 定 将 要 命 中 的 行 数。 
        上 述 我 们 提 到 的 是 一 些 基 本 的 提 高 查 询 速 度 的 注 意 事 项, 但 是 在 更 多 的
 情 况 下, 程 序 员 往 往 需 要 反 复 地 试 验 比 较 不 同 的 语 句 以 得 到 最 佳 的 方 案。 此
 外 更 为 重 要 的 是 需 要 数 据 库 管 理 员 在 数 据 库 的 服 务 器 一 端 调 整 数 据 库 管 理 系
 统 的 参 数, 以 得 到 更 快 的 响 应 性 能, 这 就 超 出 了 本 文 的 讨 论 范 围。 

                       


--
※ 来源:.紫 丁 香 bbs.hit.edu.cn.[FROM: 202.97.236.132]
--
※ 转载:.紫 丁 香 bbs.hit.edu.cn.[FROM: whs.hit.edu.cn]
--
※ 转载:.紫 丁 香 bbs.hit.edu.cn.[FROM: cadcam.hit.edu.c]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:5.249毫秒