MSSQL / Oracle查询调优500,000多条记录Coldfusion - lower()会降低性能

时间:2011-04-05 14:35:29

标签: sql-server oracle coldfusion performance

我不是要开始讨论哪个更好一般,我是专门问这个问题的。 :)

我需要编写一个查询来从包含500k +记录的数据库中撤回userid(uid)列表。我只回到了一个领域,uid。我可以查询我们的Oracle盒子或MSSQL 2000盒子。查询看起来像这样(这还没有简化)

select uid
from employeeRec
where uid = 'abc123'

是的,它只是一个查询。我需要tuninig的帮助是uid被索引,而某些uid可能(不是很多,但有些)'ABC123'或'abc123'。 MSSQL不关心区分大小写,而Oracle则关注区分大小写。所以对于Oracle,我的查询看起来像这样:

select uid
from employeeRec
where lower(uid) = 'abc123'

我已经了解到如果你在MSSQL的索引字段中使用lower,你会使索引变得无用(有很多方法但是这超出了我的问题范围 - 因为如果我选择MSSQL,我就不会t需要使用较低的)。我想知道我是否选择了Oracle,并使用了lower()函数,这会不会影响查询的性能?

除了正在运行的其他一些查询之外,我正在循环这个查询大约200次,并且每次迭代处理整个循环需要1秒,并且我已经缩短了这个特定查询的速度。对于一个网页,200秒似乎是永恒的。对于CF读者来说,超时值已经增加,因此页面没有错误输出且没有页面错误,我只是想加快这个查询。

需要注意的另一个问题:这个数据库与正在运行的其他查询位于不同的城市,因此我确实预计会有一些滞后时间。

3 个答案:

答案 0 :(得分:5)

正如TomTom所说,您的索引将不会被Oracle使用。但是,您可以创建 基于函数的索引 ,并在发出查询时使用此新索引。

create index my_new_ix on employeeRec(lower(uid));

答案 1 :(得分:3)

在函数调用中包装索引列可能会导致Oracle出现性能问题。 Oracle无法在UID上使用普通索引来处理您的查询。另一方面,您可以在lower(uid)上创建一个基于函数的索引,该索引将由查询使用,即

CREATE INDEX case_insensitive_idx
    ON employeeRec( lower( uid ) );

请注意,如果您希望一般情况下不区分大小写的查询,则可以更好地为setting NLS parameters提供服务以强制不区分大小写。您仍然需要在要搜索的列上使用基于函数的索引,但它可以简化您的查询。

答案 2 :(得分:1)

  

我想知道我是否选择了Oracle,   并使用lower()函数   这也伤害了表现   查询?

是。性能降低是因为索引在原始值上并且排序规则i区分大小写,因此必须通过函数运行所有可能的值以过滤掉匹配的值。