Sql 需要帮助为informix表构建良好的索引吗

Sql 需要帮助为informix表构建良好的索引吗,sql,indexing,informix,Sql,Indexing,Informix,我有一个Informix11.7服务器,它的数据库表有3000万行。 表架构如下所示: 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, eks

我有一个Informix11.7服务器,它的数据库表有3000万行。 表架构如下所示:

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)
);
在这个表上有6个索引,它们彼此非常相似,我认为它们写错了,这就是为什么在这个表上运行查询很慢的原因。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); 
正如您可以看到的,每个索引中的字段数据和运算符都是重复的。 有人能帮我重写它们以优化我的表吗


到目前为止,我需要像每两周一样运行
更新表ppd的统计信息,以优化表
ppd
,但这不是一个好的解决方案,对吗?

如果您的查询没有在
数据
运算符
上指定条件(最好是相等条件),那么这些索引是无用的。服务器将不得不扫描整个表,或者动态地建立索引(并删除它们)。例如,对于查询:

SELECT *
  FROM ppd
 WHERE datum = DATE('2017-11-04')
   AND operator = 'JKL'
   AND …
根据
部分中指定的条件,这些索引中的任何一个都可能有用

如果条件指定了
基准
运算符
上的范围,而不是相等,则索引的用处较小,但不一定无用。如果您执行类似于
的操作,其中运算符匹配“*”
,您将无法从索引中获益。例如:

SELECT *
  FROM ppd
 WHERE datum BETWEEN DATE('2017-11-04') AND DATE('2017-11-08')
   AND operator = 'JKL'
   AND …
优化器可能会使用索引,但它会为
BETWEEN
子句所暗示的5个日期中的每个日期记录的所有运算符值选择数据。
'JKL'
过滤器可能对优化器帮助不大。有了固定的日期和一系列运算符,您可能会从索引中获得更多好处,但仍然有一定的局限性

如果您有如下查询:

SELECT *
  FROM ppd
 WHERE client_id = 'ABC123DEF456Z'
   AND obrabot = 12345
   AND …{no mention of datum or operator}…
那么所有索引都不能使用

因此,您需要查看并显示运行缓慢的查询。您需要查看他们的查询计划(设置解释输出)。保持统计数据的更新是很重要的,但是如果优化器不能使用索引,那就没有帮助了;事实上,在这种情况下,指数的作用适得其反。在插入、更新和删除行时,它们会占用空间,需要系统进行维护,但在运行查询时不会使用它们。您可以添加索引以强制执行唯一性约束或加快查询。如果您的索引不用于这两个目的,那么它们是毫无意义的(最好删除它们)

令人担忧的是,没有一个索引也是唯一的。这意味着表上没有定义的主键。你应该有一个


请注意,还有许多其他因素会影响性能。您将此表与其他哪些表联接?您有5个
CHAR(100)
类型的列,以及数量适中的其他列;您的行大小为794字节,这意味着如果Informix在您的系统上使用2K页(每页5行,页面大小为4K),则一个页面上只能容纳2行。它们都是固定大小的字段,简化了事情。然而,与“慢SQL看起来像什么”相比,这些都是次要的问题。当然,如果您要加入其他索引不良的表,那么这种组合可能会对性能造成灾难性影响。

dam,世界上仍有人在使用informix。您在表上运行什么查询。您正在执行选择、插入/更新/删除操作。只有当数据位于where子句中时,这些索引才有用。一旦where子句中没有遇到列,通常就不能使用索引。这是一个简单的select查询,其中包含一些存储过程,这些存储过程再次从表ppd@AbBennett读取,是的,我们仍然使用informix。。。无法更改存储过程的作用是什么,它们是否在选择中?粘贴查询对我来说会更容易。我过去喜欢使用informix,因此使用
集EXPLAIN ON
的查询计划将非常有用。如果表中的数据正在更改,则始终需要定期更新统计信息。您可以尝试使用
updatestatistics MEDIUM
,看看它们是否“足够好”,因为它们比
HIGH
构建速度快得多。