我的任务是估算在报告PostgreSQL数据库中用SQL编写的查询时加入一个附加表的边际成本。我得到了一个测试程序来测试查询的性能。无论是否填充联接表,运行时之间似乎没有统计上的显著差异。如何编写更好的测试来说明这两个场景在查询时间上的差异?
在每种情况下,SQL都是相同的,将表A与表B连接起来。唯一的区别是表B是否包含任何数据。
表A有以下列:

    Column    |            Type
--------------+-----------------------------
 sid          | bigint
 cluster      | text
 sn           | text
 tag_id       | integer
 src_ip       | text
 dst_ip       | text
 dst_port     | integer
 protocol     | text
 src_intf     | text
 dst_intf     | text
 disp         | smallint
 rcvd_bytes   | bigint
 sent_bytes   | bigint
 duration     | integer
 count        | integer
 start_time   | timestamp without time zone
 policy_id    | text
 src_user     | text
 dst_domain   | text
 app_id       | text
 signature_id | text
 deny_type_id | text
 reputation   | text
 wb_cat_id    | text
 alarm_name   | text
 virus        | text
 sender       | text
 recipients   | text
 host         | text
 dlp_rule_id  | text
 spam_type    | text
 spam_action  | text

表B有以下列:
    Column    |            Type
--------------+-----------------------------
 appliance_id | integer
 ip           | inet
 fqdn         | text
 resolve_time | timestamp without time zone
 expire_time  | timestamp without time zone

这两个表由inet类型的IPv4地址连接。
测试数据用超过500行的数据填充表A和B。
在填充表B的情况下,运行查询的测试程序平均需要运行总时间的18.216秒。两次运行之间的标准偏差为1.143秒。
表B为空时,运行查询的测试程序平均需要运行总时间的18.523秒两次运行之间的标准偏差为1.928秒。
每种情况下的样本量为6次。我想我需要使用大得多的样本量,但不确定合适的样本量是多少。

最佳答案

我用左连接编写了一个简单的查询:

SELECT * FROM a
         LEFT JOIN b
                   ON a.src_ip::inet = b.ip
                   AND b.resolve_time IS NOT NULL AND b.resolve_time <= now()
                   AND b.expire_time IS NOT NULL AND now() < b.expire_time

然后,我运行了10个测试,每个测试有100个迭代(查询),并为每个测试运行的结果计时。
结果如下:
通过平均运行时间并计算填充了表B的运行时间与未填充表B的运行时间之比,我能够计算出表B的查询与未填充表B的查询的开销为21.38%。

10-05 23:06
查看更多