日期:2014-05-17  浏览次数:20832 次

速救啊,sql死慢啊,模糊查询的问题
我有两张表,一张有一万条数据左右 还有一张数据有一百万左右。


现在这两张表关联,然后取出一些数据有分组,求和,统计。关联的唯一条件就是一个字段模糊。

 SELECT T.TYDWNAME,
  T.WORKDATE,
  T.CARDNO,
  C.CARD_ID,
  C.CARD_NAME,
  COUNT(T.CARDNO),
  SUM(T.AMOUNT)
  FROM TEMP_BFHPOSLC T, CARD_BIN C
  WHERE 
  instr(T.CARDNO, C.card_id) = 1
  GROUP BY T.CARDNO, T.TYDWNAME, T.WORKDATE,C.CARD_ID,C.CARD_NAME


索引建了 但是没调用。重点就是这个模糊啊!!!!
慢得吐血啊。。。。。求高人指导啊

------解决方案--------------------
所谓的模糊,用java来描述就是 T.CARDNO.startsWith(C.card_id) ?

另外,你什么数据库呢?表结构(主要是主键、索引之类)呢?
------解决方案--------------------
另外,无论你数据库、表结构为何,你都只要count(*)而不需要count(T.CARDNO),大部分情况下,这样反而慢。
因为你已经Group by CARDNO了
------解决方案--------------------
当然没法调用了,要先JOIN,而JOIN的时候,根本没法索引。
是T.CARDNO LIKE C.card_id%吧??
------解决方案--------------------
你的表结构能够调整吗?尽量直接用=做join
------解决方案--------------------
sql优化的经验:
1.选择最有效率的表名顺序:记录数最少的表作为其表,放在最后;
2.WHERE子句中的连接顺序:那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾;
3.减少访问数据库的次数:少使用子表查询,多使用表连接;
4.使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表;
5.用Where子句替换HAVING子句避免使用HAVING子句,HAVING只会在检索出所有记录之后才对结果集进行过滤,这个处理需要排序、统计等操作;
6.用NOT EXISTS替代NOT IN:NOT IN子句将执行一个内部的排序和合并,无论在哪种情况下,NOT IN都是最低效的,因为它对子查询中的表执行了一个全表遍历;
7.用表连接替换EXISTS:通常来说,采用表连接的方式比EXISTS更有效率 ;
8.用索引提高效率;
9.避免在索引列上使用IS NULL和IS NOT NULL ;
10.使用UNION-ALL代替UNION ;
------解决方案--------------------
探讨

引用:
你的表结构能够调整吗?尽量直接用=做join


好像不可以 银行卡前几位代表卡的种类 后面才是每个人不同 模糊的就是前面的几位

------解决方案--------------------
因为使用了函数,SQL就会自动的放弃使用索引采用全表扫描。
------解决方案--------------------
另外,如果那个card_id是固定长度的话,你可以使用orace的Function-based index
http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_5010.htm#i2092987

create index card_type_index on TEMP_BFHPOSLC (LEFT(card_no), 5)

------解决方案--------------------
你确定使用交叉连接而不是inner join连接?
------解决方案--------------------
实在不行的话,就加一个字段来存储匹配的那部分数据。那样就可以用相等性判断了,效果会显著提高。