慢SQL查询,如何改进?

时间:2013-05-24 15:32:39

标签: java html sql jsp jstl

我认为这个查询完美无缺。除了这么慢。我究竟做错了什么?如何在一般代码中提高速度?

<sql:query var="UserQuery" dataSource="jdbc/UBWT">
SELECT top 100 
dbo.v_r_system.Name0                                        as PC,
dbo.v_computer_owners_preferred.User_ID                     as UBOCUBID,
dbo.v_r_user.User_Name0                                     as UBID,
dbo.v_r_user.ResourceID                                     as ResID,
dbo.v_r_user.displayName0                                   as FoolName,
dbo.v_r_user.givenName0                                     as FirstName,          
dbo.v_r_user.sn0                                            as LastName,
dbo.v_r_user.mail0                                          as eMail,
dbo.v_computer_owners_preferred.Recent_Login_TimeStamp      as InFor,
dbo.v_r_user.departmentNumber0                              as DeptNum,
dbo.v_r_user.department0                                    as Dept,
dbo.v_r_user.telephoneNumber0                               as Phone
FROM        
dbo.v_r_system
inner join dbo.v_computer_owners_preferred on dbo.v_r_system.name0 = dbo.v_computer_owners_preferred.computer_name
inner join dbo.v_r_user on dbo.v_computer_owners_preferred.user_id = dbo.v_r_user.unique_user_name0
where dbo.v_r_system.Name0 = ? <sql:param value="${param.ubid}" />
or dbo.v_computer_owners_preferred.User_ID = ? <sql:param value="${param.ubid}" />
or dbo.v_r_user.User_Name0 = ? <sql:param value="${param.ubid}" />
or dbo.v_r_user.displayName0 = ? <sql:param value="${param.ubid}" />
or dbo.v_r_user.telephoneNumber0 = ? <sql:param value="${param.ubid}" />
order by dbo.v_computer_owners_preferred.Recent_Login_TimeStamp desc;

我真的不喜欢所有OR语句。我是否需要转换为某种 准备好的 声明?

4 个答案:

答案 0 :(得分:3)

使用EXPLAIN PLAN查看查询速度慢的原因。如果您看到TABLE SCAN,请删除它们。或者通过重新排列WHERE子句来缩小扫描集的大小。

索引可能会有所作为。对于WHERE子句中出现的每一列,您应该有一个。

答案 1 :(得分:1)

乍一看,您的查询没有任何问题,而且没有任何问题,或者&#39;或&#39;无论是。与数据库所有者交谈,以调查数据库中哪些列和列组合索引。查询优化器可能通过数据库表求助于滚动。

相当平淡的回答,我知道但不多说。

答案 2 :(得分:0)

如果查询返回大量结果而不将其限制为100,则可能是您遇到的问题。

由于您拥有ORDER BY语句意味着如果您使用查询返回10,000,000行,它会在排名前100并将其返回给您之前订购所有行,但是如果您离开out,它只会返回它遇到的前100个结果。

我能想到的唯一方法就是在表上获得正确的索引,或者返回Recent_Login_Timestamp在合理范围内的所有结果(即如果有很多条目,则返回一天)。

答案 3 :(得分:0)

通常我注意到 JSTL SQL taglib比Java代码慢得多,因为它将所有结果集放入HashMap。我认为它应该只用于原型设计。

无论如何,您可以尝试以下列方式简化where子句,看看它是否有帮助:

where ? <sql:param value="${param.ubid}" /> in (
    dbo.v_r_system.Name0,
    dbo.v_computer_owners_preferred.User_ID,
    dbo.v_r_user.User_Name0,
    dbo.v_r_user.displayName0,
    dbo.v_r_user.telephoneNumber0
    )