oracle 如何提高查询速度
在一个项目中用户登录要每次查询未读的信息,我写的未读信息存储过程如下:
CREATE OR REPLACE PACKAGE returnPackage AS
TYPE returnCursor IS REF CURSOR;
END returnPackage;
/
---------------------------------------------------------------
CREATE OR REPLACE PROCEDURE listUnread(
param_lgname IN VARCHAR2,
param_r IN VARCHAR2,
resultCursor OUT returnPackage.returnCursor
) AS
op_type_receive CHAR(1);
lgname VARCHAR2(30);
BEGIN
op_type_receive := TRIM(param_r);
lgname := TRIM(param_lgname);
OPEN resultCursor FOR
SELECT DISTINCT
mb.dbid,
mb.parentDbid,
TRIM(mb.sender) AS sender,
TRIM(mb.receipt) AS receipt,
mb.type,
mb.mailDate,
mb.subject,
mb.attachNums
FROM
mailbox mb
LEFT OUTER JOIN
groups gp
ON
TRIM(gp.memberLoginName) = lgname
LEFT OUTER JOIN
ts_op_stream op
ON
mb.dbid = op.dbid AND op.op_status = op_type_receive
WHERE
op.op_status IS NULL
AND (
TRIM(mb.receipt) = lgname
OR
TRIM(mb.receipt) = TRIM(gp.groupLoginName)
OR
INSTR(',' || TRIM(mb.receipt) || ',', ',' || lgname || ',') > 0
OR
INSTR(',' || TRIM(mb.receipt) || ',', ',' || TRIM(gp.groupLoginName) || ',') > 0
)
ORDER BY mailDate DESC;
END listUnread;
/
在很多用户登录的时候发现会很慢,我目前想创建索引来提高速度,如下:
create index mailbox_date on mailbox(mailDate desc);
另外大家有没有好的方法来提高查询速度,多多指出,谢谢!
------解决方案--------------------
未读的信息只有1个可能,那就是
1 收件人是自己
2 阅读状态是false
索引2个,
1是收件人,
2是阅读状态
这个查询一个select 足以,
你的存储过程我就不仔细看了,如果不能满足需求,那就完善你的数据结构吧!
分组消息要发到个人的收件箱,不要有什么组消息。用空间来换取速度是值得的。毕竟硬盘都T级别了!
------解决方案--------------------你join的条件,where子句的qualification没有用到date相关的条件,所以,不需要对date建索引
建议:
1。先把receipt trim好存到数据库里,然后用对它建索引
2。对status建索引
------解决方案--------------------在给定的系统硬件和系统软件条件下,提高数据库系统的运行效率的办法是:
(1) 在数据库物理设计时,降低范式,增加冗余, 少用触发器, 多用存储过程。
(2) 当计算非常复杂、而且记录条数非常巨大时(例如一千万条),复杂计算要先在数据库外面,以文件系统方式用C++语言计算处理完成之后,最后才入库追加到表中去。这是电信计费系统设计的经验。
(3) 发现某个表的记录太多,例如超过一千万条,则要对该表进行水平分割。水平分割的做法是,以该表主键PK的某个值为界线,将该表的记录水平分割为两个表。若发现某个表的字段太多,例如超过八十个,则垂直分割该表,将原来的一个表分解为两个表。
(4) 对数据库管理系统DBMS进行系统优化,即优化各种系统参数,如缓冲区个数。
(5) 在使用面向数据的SQL语言进行程序设计时,尽量采取优化算法。
------解决方案--------------------
做为一个程序员一般只停留在对SQL语句的优化上面,
呵呵,至少目前我还是这个层次.
下面是一些常用的对操作符的优化方法:
操作符优化
IN 操作符
用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格。
但是用IN的SQL性能总是比较低的,从ORACLE执行的步骤来分析用IN的SQL与不用IN的SQL有以下区别:
ORACLE试图将其转换成多个表的连接,如果转换不成功则先执行IN里面的子查询,再查询外层的表记录,如果转换成功则直接采用多个表的连接方式查询。由此可见用IN的SQL至少多了一个转换的过程。一般的SQL都可以转换成功,但对于含有分组统计等方面的SQL就不能转换了。
推荐方案:在业务密集的SQL当中尽量不采用IN操作符。
NOT IN操作符
此操作是强列推荐不使用的,因为它不能应用表的索引。
推荐方案:用NOT EXISTS 或(外连接+判断为空)方案代替
<> 操作符(不等于)
不等于操作符是永远不会用到索引的,因此对它的处理只会产生全表扫描。