如何 SELECT table X 中具有最大值的单个记录 X.a WHERE 指定字段 X.b 和 X.c 的值
How to SELECT a single record in table X with the largest value for X.a WHERE values for fields X.b & X.c are specified
我正在使用以下查询从交易历史记录中的最新记录中获取主机设备 (tr_host_sn
) 上安装的当前组件序列号 (tr_sim_sn
) table (PUB.tr_hist
)
SELECT tr_sim_sn FROM PUB.tr_hist
WHERE tr_trnsactn_nbr = (SELECT max(tr_trnsactn_nbr)
FROM PUB.tr_hist
WHERE tr_domain = 'vattal_us'
AND tr_lot = '99524136'
AND tr_part = '6684112-001')
实际 table 有大约 1.9 亿条记录。下面的摘录仅包含一些示例记录,并且仅包含与搜索相关的字段以说明上面的查询:
tr_sim_sn |tr_host_sn* |tr_host_pn |tr_domain |tr_trnsactn_nbr |tr_qty_loc
_______________|____________|_______________|___________|________________|___________
... |
356136072015140|99524135 |6684112-000 |vattal_us |178415271 |-1.0000000000
356136072015458|99524136 |6684112-001 |vattal_us |178424418 |-1.0000000000
356136072015458|99524136 |6684112-001 |vattal_us |178628048 |1.0000000000
356136072015050|99524136 |6684112-001 |vattal_us |178628051 |-1.0000000000
356136072015836|99524137 |6684112-005 |vattal_us |178645337 |-1.0000000000
...
*
= key field
该摘录说明了 tr_host_sn
的单个值多次出现 tr_trnsactn_nbr
。 tr_trnsactn_nbr
的最大值对应于 tr_host_sn
内安装的当前 tr_sim_sn
。
这个查询有效,但是很慢,大约 8 分钟。
对于改进或重构此查询以提高其速度的建议,我将不胜感激。
请与您的管理员联系以确定他们上次更新 SQL 统计信息的时间。如果答案是“我们不知道”或“从不”,那么您可能希望他们 运行 以下 4gl 程序将创建一个 SQL 脚本来完成此操作:
/* genUpdateSQL.p
*
* mpro dbName -p util/genUpdateSQL.p -param "tmp/updSQLstats.sql"
*
* sqlexp -user userName -password passWord -db dnName -S servicePort -infile tmp/updSQLstats.sql -outfile tmp/updSQLtats.log
*
*/
output to value( ( if session:parameter <> "" then session:parameter else "updSQLstats.sql" )).
for each _file no-lock where _hidden = no:
put unformatted
"UPDATE TABLE STATISTICS AND INDEX STATISTICS AND ALL COLUMN STATISTICS FOR PUB."
'"' _file._file-name '"' ";"
skip
.
put unformatted "commit work;" skip.
end.
output close.
return.
这将生成一个脚本,用于更新所有 table 和所有索引的统计信息。如果需要,您可以编辑输出以仅更新属于此查询的 tables 和索引。
此外,如果管理员感到紧张,他们当然可以在生产环境中实施之前在测试数据库或还原的备份上尝试此操作。
我post将此作为对我请求改进查询的回应。
事实证明,以下语法具有两个截然不同的特点,大大提高了查询速度。一种是在查询的主要部分和嵌套部分都包含 tr_domain
搜索条件。二是通过增加搜索条件的数量来缩小搜索范围,以下均包含在语法的嵌套部分中:
SELECT tr_sim_sn,
FROM PUB.tr_hist
WHERE tr_domain = 'vattal_us'
AND tr_trnsactn_nbr IN (
SELECT MAX(tr_trnsactn_nbr)
FROM PUB.tr_hist
WHERE tr_domain = 'vattal_us'
AND tr_part = '6684112-001'
AND tr_lot = '99524136'
AND tr_type = 'ISS-WO'
AND tr_qty_loc < 0)
此语法导致大约 0.5 秒的响应时间。 (感谢我的同事 Daniel V.)
公平地说,此查询使用的标准超出了原始 post 中包含的最初陈述的参数,这使得其他人很难甚至不可能尝试合理的答案。这种遗漏当然不是故意的,而是由于对良好查询设计的基础知识相当陌生。此查询部分是由于了解到当 too-few 或 non-indexed 字段用作大型 table 中的搜索条件时,有时通过增加字段数量来缩小搜索范围会有所帮助搜索条件项。原来有3个,这个有5个
我正在使用以下查询从交易历史记录中的最新记录中获取主机设备 (tr_host_sn
) 上安装的当前组件序列号 (tr_sim_sn
) table (PUB.tr_hist
)
SELECT tr_sim_sn FROM PUB.tr_hist
WHERE tr_trnsactn_nbr = (SELECT max(tr_trnsactn_nbr)
FROM PUB.tr_hist
WHERE tr_domain = 'vattal_us'
AND tr_lot = '99524136'
AND tr_part = '6684112-001')
实际 table 有大约 1.9 亿条记录。下面的摘录仅包含一些示例记录,并且仅包含与搜索相关的字段以说明上面的查询:
tr_sim_sn |tr_host_sn* |tr_host_pn |tr_domain |tr_trnsactn_nbr |tr_qty_loc
_______________|____________|_______________|___________|________________|___________
... |
356136072015140|99524135 |6684112-000 |vattal_us |178415271 |-1.0000000000
356136072015458|99524136 |6684112-001 |vattal_us |178424418 |-1.0000000000
356136072015458|99524136 |6684112-001 |vattal_us |178628048 |1.0000000000
356136072015050|99524136 |6684112-001 |vattal_us |178628051 |-1.0000000000
356136072015836|99524137 |6684112-005 |vattal_us |178645337 |-1.0000000000
...
*
= key field
该摘录说明了 tr_host_sn
的单个值多次出现 tr_trnsactn_nbr
。 tr_trnsactn_nbr
的最大值对应于 tr_host_sn
内安装的当前 tr_sim_sn
。
这个查询有效,但是很慢,大约 8 分钟。
对于改进或重构此查询以提高其速度的建议,我将不胜感激。
请与您的管理员联系以确定他们上次更新 SQL 统计信息的时间。如果答案是“我们不知道”或“从不”,那么您可能希望他们 运行 以下 4gl 程序将创建一个 SQL 脚本来完成此操作:
/* genUpdateSQL.p
*
* mpro dbName -p util/genUpdateSQL.p -param "tmp/updSQLstats.sql"
*
* sqlexp -user userName -password passWord -db dnName -S servicePort -infile tmp/updSQLstats.sql -outfile tmp/updSQLtats.log
*
*/
output to value( ( if session:parameter <> "" then session:parameter else "updSQLstats.sql" )).
for each _file no-lock where _hidden = no:
put unformatted
"UPDATE TABLE STATISTICS AND INDEX STATISTICS AND ALL COLUMN STATISTICS FOR PUB."
'"' _file._file-name '"' ";"
skip
.
put unformatted "commit work;" skip.
end.
output close.
return.
这将生成一个脚本,用于更新所有 table 和所有索引的统计信息。如果需要,您可以编辑输出以仅更新属于此查询的 tables 和索引。
此外,如果管理员感到紧张,他们当然可以在生产环境中实施之前在测试数据库或还原的备份上尝试此操作。
我post将此作为对我请求改进查询的回应。
事实证明,以下语法具有两个截然不同的特点,大大提高了查询速度。一种是在查询的主要部分和嵌套部分都包含 tr_domain
搜索条件。二是通过增加搜索条件的数量来缩小搜索范围,以下均包含在语法的嵌套部分中:
SELECT tr_sim_sn,
FROM PUB.tr_hist
WHERE tr_domain = 'vattal_us'
AND tr_trnsactn_nbr IN (
SELECT MAX(tr_trnsactn_nbr)
FROM PUB.tr_hist
WHERE tr_domain = 'vattal_us'
AND tr_part = '6684112-001'
AND tr_lot = '99524136'
AND tr_type = 'ISS-WO'
AND tr_qty_loc < 0)
此语法导致大约 0.5 秒的响应时间。 (感谢我的同事 Daniel V.)
公平地说,此查询使用的标准超出了原始 post 中包含的最初陈述的参数,这使得其他人很难甚至不可能尝试合理的答案。这种遗漏当然不是故意的,而是由于对良好查询设计的基础知识相当陌生。此查询部分是由于了解到当 too-few 或 non-indexed 字段用作大型 table 中的搜索条件时,有时通过增加字段数量来缩小搜索范围会有所帮助搜索条件项。原来有3个,这个有5个