数据库案例不敏感指数?

时间:2008-08-15 22:47:57

标签: sql database oracle indexing db2

我有一个查询,我在搜索字符串:

SELECT county FROM city WHERE UPPER(name) = 'SAN FRANCISCO';

现在,这种方法很好,但它不能很好地扩展,我需要优化它。我有found an option沿着创建生成视图的方式,或类似的东西,但我希望使用索引的更简单的解决方案。

我们正在使用DB2,我真的想使用expression in an index,但是这个选项似乎只能在z / OS上使用,但我们运行的是Linux。我还是尝试了表达式索引:

CREATE INDEX city_upper_name_idx
ON city UPPER(name) ALLOW REVERSE SCANS;

但当然,它在UPPER(名字)上窒息。

我是否有另一种方法可以以这种方式创建索引或类似内容,这样我就不必重新构建现有查询以使用新生成的视图,或更改现有列,或任何其他此类侵入式更改?

编辑:我愿意听取其他数据库的解决方案......它可能会延续到DB2 ......

6 个答案:

答案 0 :(得分:7)

您可以添加一个包含城市名称的数字哈希键的索引列。 (允许重复)。

然后你可以做一个多子句:

hash = [compute hash key for 'SAN FRANCISCO']

SELECT county 
FROM city 
WHERE cityHash = hash 
  AND UPPER(name) = 'SAN FRANCISCO' ;

或者,浏览db手册并查看创建表索引的选项。可能会有所帮助。

答案 1 :(得分:5)

简短回答,不。

答案很长,是的,如果你在大型机上运行,​​但你不是,所以你必须使用其他技巧。

DB2(从DB2 / LUW v8开始)现在已生成列,因此您可以:

CREATE TABLE tbl (
    lname  VARCHAR(20),
    fname  VARCHAR(20),
    ulname VARCHAR(20) GENERATED ALWAYS AS UPPER(lname)
);

然后在ulname上创建索引。我不确定你会比这更简单。

在此之前,您曾经必须使用插入和更新触发器的组合来确保ulname列保持同步,这是一个维护的噩梦。此外,既然此功能是核心DBMS的一部分,它已经过高度优化(它比基于触发器的解决方案快得多),并且不会妨碍真正的用户触发器,因此无需维护额外的DB对象。 / p>

有关详细信息,请参阅here

答案 2 :(得分:1)

DB2在整理方面不强。它没有基于功能的索引。

Niek Sanders的建议可行,如果你能接受哈希必须在你的应用程序中发生(因为据我所知,DB2没有SHA或MD5函数)。

但是,如果我是你,我将使用CREATE TABLE AS创建一个物化视图(MQT ==物化查询表,在db2用语中),添加一个列,其中包含预先计算的大写变体名称。注意:您可以在DB2中为实现视图添加索引。

答案 3 :(得分:1)

PostgreSQL还支持索引函数的结果:

CREATE INDEX mytable_lower_col1_idx ON mytable (lower(col1));

我能想到的唯一另一个选择是通过创建另一个列来保存大写版本(由触发器更新)并对其进行索引来对数据进行一些标准化。布莱什!

答案 4 :(得分:1)

我不知道这是否适用于DB2,但我会告诉你我是如何在SQL Server中这样做的。我认为 MSSQL这样做的方式是ANSI标准,尽管特定的排序字符串可能不同。无论如何,如果你可以做到这一点而不会破坏你的应用程序的其余部分 - 还有其他地方,“名称”列需要区分大小写吗? - 尝试通过更改排序规则使整个列不区分大小写,然后将列索引。

ALTER TABLE city ALTER COLUMN name nvarchar(200) 
    COLLATE SQL_Latin1_General_CP1_CI_AS

...其中“nvarchar(200)”代表您当前的列数据类型。排序字符串的“CI”部分标记为在MSSQL中不区分大小写。

要解释......我的理解是索引将按索引列的排序规则的顺序存储值。使列的排序规则不区分大小写将使索引存储“旧金山”,“旧金山”和“旧金山”全部合并在一起。然后你应该从查询中删除“UPPER()”,DB2应该知道它可以使用你的索引。

同样,这完全基于我对SQL Server的了解,加上几分钟的SQL-92规范;它可能适用于DB2也可能不适用。

答案 5 :(得分:1)

Oracle支持基于函数的索引。他们的典型例子:

 create index emp_upper_idx on emp(upper(ename));