我的任务是估算在报告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%。