让Hibernate在外键上生成索引

让Hibernate在外键上生成索引,hibernate,postgresql,indexing,foreign-keys,Hibernate,Postgresql,Indexing,Foreign Keys,我在一个相当大的项目中使用Hibernate 3.3.2,PostgreSQL 8.4使用PostgreSQL方言 按照建立关系的方式,我们最终会对表的外键属性进行大量搜索 出于性能原因,我希望在使用hbm2dll.auto创建表时,让Hibernate向所有外键列添加索引 MySQL会自动为这些列添加索引,但在Postgres中似乎没有这样做的方法 是否可以在某个地方设置一个选项,或者在hbm.xml文件中添加一些内容来实现这一点?Hibernate仅对MySQL强制indexcreation

我在一个相当大的项目中使用Hibernate 3.3.2,PostgreSQL 8.4使用PostgreSQL方言

按照建立关系的方式,我们最终会对表的外键属性进行大量搜索

出于性能原因,我希望在使用hbm2dll.auto创建表时,让Hibernate向所有外键列添加索引

MySQL会自动为这些列添加索引,但在Postgres中似乎没有这样做的方法


是否可以在某个地方设置一个选项,或者在hbm.xml文件中添加一些内容来实现这一点?

Hibernate仅对MySQL强制indexcreation,而不是对PostgreSQL、Oracle等。MySQL不允许没有索引的外键,其他数据库没有此限制

Sybase有一个为什么不强制执行索引是件好事,还有一个关于它的主题(与Oracle相关),包括一个解决方法。但在开始创建大量索引之前,请检查是否需要所有这些索引。在许多情况下,这些索引可以与其他索引相结合以加快速度。这要看情况了

在查询中使用“解释”查看数据库如何执行查询、使用了哪些索引、缺少索引的位置等。

请尝试以下任一方法:

<many-to-one name="master" class="Master" column="master_id" index="my_index_name" />

<many-to-one name="master" class="Master">
    <column name="master_id" index="my_index_name" />
</many-to-one>

下面是一个快速而肮脏的查询,它将为架构中每个已定义外键的索引生成DDL:

SELECT 'CREATE INDEX fk_' || conname || '_idx ON ' 
       || relname || ' ' || 
       regexp_replace(
           regexp_replace(pg_get_constraintdef(pg_constraint.oid, true), 
           ' REFERENCES.*$','',''), 'FOREIGN KEY ','','') || ';'
FROM pg_constraint 
JOIN pg_class 
    ON (conrelid = pg_class.oid)
JOIN pg_namespace
    ON (relnamespace = pg_namespace.oid)
WHERE contype = 'f'
  AND nspname = 'public';
这只在PostgreSQL 8.4中进行了测试,但我认为它应该在大多数8.x版本中都能工作


还要注意的是,这并没有检测到索引中已经包含了哪些内容,因此您可能会有一些重复。

除了Matthew的答案之外: 添加


就在分号之前,仅当索引不存在时才创建索引。这允许您重复执行语句,而不产生“关系fk_……”已存在“错误。

不强制外键具有索引是很有意义的,但允许这样做似乎是一个不错的选择。我尝试了这两种方法,但在数据库中搜索本应创建的索引不会产生任何结果=\n不确定我可能做错了什么,但会一直插上。你用的是什么设置?也许它们没有添加“更新”,但会添加“创建”或“创建删除”?另一个想法是,这可能是一个类似这样的错误:一旦建立了数据库,这是有帮助的,但对于这个问题,我更感兴趣的是让hibernate在创建表时为我做这件事。对于我的另一个相关问题,这是一个很好的答案:我认为,它对带引号的命名变量不起作用。@Ravshan:暂时忽略不应该在数据库表定义中使用带引号的名称,这在9.3:选择不同的regexp_替换(regexp_替换(pg_get_constraintdef(oid))中似乎对我有效,“^.*”引用“,”在“,”上创建索引“,”).*$,”;”)来自pg_约束,其中contype='f'。有时不可避免地使用带引号的标识符(至少出于遗留目的)。
AND NOT EXISTS (
  SELECT * FROM pg_class pgc
    JOIN pg_namespace pgn ON (pgc.relnamespace = pgn.oid)
  WHERE relkind='i'
    AND pgc.relname = ('fk_' || conname || '_idx') )