我在使用PostgreSQLDialect的PostgreSQL 8.4的一个相当大的项目中使用Hibernate 3.3.2。
我们建立关系的方式,最终我们对表的外键属性进行了大量搜索。
出于性能原因,我希望Hibernate在使用hbm2dll.auto创建表时为所有外键列添加索引。
MySQL会自动为这些列添加索引,但似乎没有办法在Postgres中执行此操作。
我可以在某个地方设置一个选项,或者我可以添加到我的hbm.xml文件中以实现此目的吗?
答案 0 :(得分:2)
Hibernate只强制执行MySQL的索引创建,而不是PostgreSQL,Oracle等.MySQL不允许没有索引的外键,其他数据库没有这个限制。
Sybase有一个explanation为什么不执行索引是一件好事,Hibernate forum也有一个关于它的主题(与Oracle相关),包括一个解决方法。但在开始创建大量索引之前,请开始检查是否需要所有这些索引。在许多情况下,索引可以与其他索引相结合以加快速度。这完全取决于!
对查询使用EXPLAIN以查看数据库如何执行它们,使用哪些索引,缺少索引的位置等。
答案 1 :(得分:2)
这是一个快速而肮脏的查询,它将为模式中每个定义的外键的索引生成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版本。
另请注意,这不会检测索引已涵盖哪些索引,因此您可能会有一些重复。
答案 2 :(得分:1)
尝试以下任一方式:
<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>
答案 3 :(得分:0)
除了马修的回答: 添加
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') )
分号之前的只在不存在的情况下才创建索引。这允许您重复执行语句而不产生“关系fk _...”已存在“错误。