需要帮助为 informix table 构建良好的索引
Need help building good indexes for informix table
我有一个 Informix 11.7 服务器,其数据库 table 有 3000 万行。
table 架构是这样的:
CREATE TABLE ppd (
datum DATE,
obrabot INTEGER,
rb_obr INTEGER,
blag_sif_transakcija INTEGER,
tip_transakcija CHAR(20),
tabela_kod CHAR(5),
vrska_sif_transakcija INTEGER,
ekspozitura CHAR(3),
valuta CHAR(3),
iznos_p DECIMAL(20,2),
iznos_d DECIMAL(20,2),
smetka CHAR(15),
podsmetka CHAR(9),
client_id CHAR(13),
client_tip CHAR(1),
client_naziv CHAR(100),
adresa CHAR(100),
edb CHAR(13),
pasos CHAR(20),
maticen_broj CHAR(20),
vid_rabota CHAR(2),
smetka_primac CHAR(15),
naziv_primac CHAR(100),
broj_primac CHAR(20),
smetka_davac CHAR(15),
naziv_davac CHAR(100),
broj_davac CHAR(20),
edb_fl CHAR(13),
sifra_plakanje CHAR(6),
namena CHAR(100),
vo_valuta CHAR(3),
vo_iznos DECIMAL(20,2),
datum_vreme DATETIME YEAR TO SECOND,
operator CHAR(3),
flag INTEGER,
potpisnik CHAR(10)
);
在这个 table 上有 6 个索引,它们彼此非常相似,我认为它们写错了,这就是 运行ning 查询这个 [=23] 的原因=] 很慢。对于 19000 行,需要 30 分钟。
索引如下所示:
CREATE INDEX ix_ppd_1 ON ppd (datum,operator,client_id,obrabot);
CREATE INDEX ix_ppd_2 ON ppd (datum,operator,edb,obrabot);
CREATE INDEX ix_ppd_3 ON ppd (datum,operator,maticen_broj,obrabot);
CREATE INDEX ix_ppd_4 ON ppd (datum,operator,rb_obr,obrabot);
CREATE INDEX ix_ppd_5 ON ppd (datum,operator,edb,edb_fl);
CREATE INDEX ix_ppd_6 ON ppd (datum,operator,rb_obr,tabela_kod);
如您所见,字段数据和运算符在每个索引中重复。
有人可以帮我重写它们以优化我的table吗?
直到现在我需要每 2 周 运行 UPDATE STATISTICS HIGH FOR TABLE ppd
来优化 table ppd
,但这不是一个好的解决方案,对吧?
如果您的查询没有在 datum
和 operator
上指定条件(最好是相等条件),那么这些索引是无用的。服务器将不得不求助于扫描整个 table,或即时构建索引(并删除它们)。例如,查询:
SELECT *
FROM ppd
WHERE datum = DATE('2017-11-04')
AND operator = 'JKL'
AND …
这些索引中的任何一个都可能有用,具体取决于 …
部分中指定的条件。
如果条件在 datum
或 operator
上指定范围而不是相等,则索引不太有用,但不一定无用。如果您执行类似 WHERE operator MATCHES '*'
的操作,您将无法从索引中获益。例如:
SELECT *
FROM ppd
WHERE datum BETWEEN DATE('2017-11-04') AND DATE('2017-11-08')
AND operator = 'JKL'
AND …
优化器可能会使用索引,但它会 select 为 BETWEEN
子句隐含的 5 个日期中的每个日期记录的所有运算符值的数据。 'JKL'
过滤器可能对优化器帮助不大。使用固定日期和一系列运算符,您可能会从索引中获得更多好处,但它仍然有些有限。
如果您有这样的查询:
SELECT *
FROM ppd
WHERE client_id = 'ABC123DEF456Z'
AND obrabot = 12345
AND …{no mention of datum or operator}…
那么 none 个索引就可以使用了。
因此,您需要查看并显示慢速 运行ning 查询。您需要查看他们的查询计划(SET EXPLAIN 输出)。保持统计数据更新很重要,但如果优化器不能使用索引,那也无济于事;事实上,在那种情况下,索引会适得其反。它们占用 space 并且需要系统在插入、更新、删除行时进行维护 — 但当查询为 运行 时它们不会被使用。您添加索引以强制执行唯一性约束或加速查询。如果你的索引不用于任何一个目的,它们就毫无意义(你最好放弃它们)。
令人担忧的是 none 的索引也是唯一的。这意味着您在 table 上没有定义的主键。你应该有一个。
请注意,还有多个其他因素会影响性能。你和其他哪些 table 一起加入这个?您有 5 个 CHAR(100)
类型的列和中等数量的其他列;您的行大小为 794 字节,这意味着如果 Informix 在您的系统上使用 2K 页面(每页 5 行,页面大小为 4K),则页面只能容纳 2 行。它们都是固定大小的字段,可以简化事情。然而,与"what does the slow SQL look like"相比,这些都是非常次要的问题。当然,如果您要加入其他索引不正确的 table,那么这种组合可能会对性能造成灾难性影响。
我有一个 Informix 11.7 服务器,其数据库 table 有 3000 万行。 table 架构是这样的:
CREATE TABLE ppd (
datum DATE,
obrabot INTEGER,
rb_obr INTEGER,
blag_sif_transakcija INTEGER,
tip_transakcija CHAR(20),
tabela_kod CHAR(5),
vrska_sif_transakcija INTEGER,
ekspozitura CHAR(3),
valuta CHAR(3),
iznos_p DECIMAL(20,2),
iznos_d DECIMAL(20,2),
smetka CHAR(15),
podsmetka CHAR(9),
client_id CHAR(13),
client_tip CHAR(1),
client_naziv CHAR(100),
adresa CHAR(100),
edb CHAR(13),
pasos CHAR(20),
maticen_broj CHAR(20),
vid_rabota CHAR(2),
smetka_primac CHAR(15),
naziv_primac CHAR(100),
broj_primac CHAR(20),
smetka_davac CHAR(15),
naziv_davac CHAR(100),
broj_davac CHAR(20),
edb_fl CHAR(13),
sifra_plakanje CHAR(6),
namena CHAR(100),
vo_valuta CHAR(3),
vo_iznos DECIMAL(20,2),
datum_vreme DATETIME YEAR TO SECOND,
operator CHAR(3),
flag INTEGER,
potpisnik CHAR(10)
);
在这个 table 上有 6 个索引,它们彼此非常相似,我认为它们写错了,这就是 运行ning 查询这个 [=23] 的原因=] 很慢。对于 19000 行,需要 30 分钟。 索引如下所示:
CREATE INDEX ix_ppd_1 ON ppd (datum,operator,client_id,obrabot);
CREATE INDEX ix_ppd_2 ON ppd (datum,operator,edb,obrabot);
CREATE INDEX ix_ppd_3 ON ppd (datum,operator,maticen_broj,obrabot);
CREATE INDEX ix_ppd_4 ON ppd (datum,operator,rb_obr,obrabot);
CREATE INDEX ix_ppd_5 ON ppd (datum,operator,edb,edb_fl);
CREATE INDEX ix_ppd_6 ON ppd (datum,operator,rb_obr,tabela_kod);
如您所见,字段数据和运算符在每个索引中重复。 有人可以帮我重写它们以优化我的table吗?
直到现在我需要每 2 周 运行 UPDATE STATISTICS HIGH FOR TABLE ppd
来优化 table ppd
,但这不是一个好的解决方案,对吧?
如果您的查询没有在 datum
和 operator
上指定条件(最好是相等条件),那么这些索引是无用的。服务器将不得不求助于扫描整个 table,或即时构建索引(并删除它们)。例如,查询:
SELECT *
FROM ppd
WHERE datum = DATE('2017-11-04')
AND operator = 'JKL'
AND …
这些索引中的任何一个都可能有用,具体取决于 …
部分中指定的条件。
如果条件在 datum
或 operator
上指定范围而不是相等,则索引不太有用,但不一定无用。如果您执行类似 WHERE operator MATCHES '*'
的操作,您将无法从索引中获益。例如:
SELECT *
FROM ppd
WHERE datum BETWEEN DATE('2017-11-04') AND DATE('2017-11-08')
AND operator = 'JKL'
AND …
优化器可能会使用索引,但它会 select 为 BETWEEN
子句隐含的 5 个日期中的每个日期记录的所有运算符值的数据。 'JKL'
过滤器可能对优化器帮助不大。使用固定日期和一系列运算符,您可能会从索引中获得更多好处,但它仍然有些有限。
如果您有这样的查询:
SELECT *
FROM ppd
WHERE client_id = 'ABC123DEF456Z'
AND obrabot = 12345
AND …{no mention of datum or operator}…
那么 none 个索引就可以使用了。
因此,您需要查看并显示慢速 运行ning 查询。您需要查看他们的查询计划(SET EXPLAIN 输出)。保持统计数据更新很重要,但如果优化器不能使用索引,那也无济于事;事实上,在那种情况下,索引会适得其反。它们占用 space 并且需要系统在插入、更新、删除行时进行维护 — 但当查询为 运行 时它们不会被使用。您添加索引以强制执行唯一性约束或加速查询。如果你的索引不用于任何一个目的,它们就毫无意义(你最好放弃它们)。
令人担忧的是 none 的索引也是唯一的。这意味着您在 table 上没有定义的主键。你应该有一个。
请注意,还有多个其他因素会影响性能。你和其他哪些 table 一起加入这个?您有 5 个 CHAR(100)
类型的列和中等数量的其他列;您的行大小为 794 字节,这意味着如果 Informix 在您的系统上使用 2K 页面(每页 5 行,页面大小为 4K),则页面只能容纳 2 行。它们都是固定大小的字段,可以简化事情。然而,与"what does the slow SQL look like"相比,这些都是非常次要的问题。当然,如果您要加入其他索引不正确的 table,那么这种组合可能会对性能造成灾难性影响。