海量数据,datetime字段做索引非常慢,怎么处理?怎么处理?求大牛,求大牛,求大牛
海量数据,datetime字段做索引非常慢,怎么办?怎么办????求大牛,,,求大牛,,,求大牛
我有一个表大概有5百万条数据,表结构大致如下:
id (int 类型,自增主键+聚集索引)
i_本级代理id (int 类型,非聚集索引)
i_下级代理id (int 类型,非聚集索引)
i_本级占成金额
.....其它字段略
i_结单时间 (datetime类型, 非聚集索引)
***************************************************
我的SQL语句如下(大致返回20条数据行,用时27秒)
****************************************************
问题:
当我把【 (A.i_结单时间 between @startsj AND @endjs)】 条件去掉,测试只要2.3秒
也就是说,只要加了【i_结单时间 】字段查询,效率就慢了几十倍,但这个字段我是有加索引的。
如果说数据表太大导致慢也没道理,如果是数据量问题,应该没加这个条件会更慢
另外我这个表几乎每秒钟都在写入数据,不知道会不会跟这个有关系
------解决方案--------------------
并非索引问题,而是楼主sql 语句写法有问题——select 中不要嵌套查询了
------解决方案--------------------
改写SQL语句,另外set statistics io on/set statistics time on 看看结果 最好也能贴出来
------解决方案--------------------
A.i_结单时间 有没有null的情况,如果有 在where 条件 加 A.i_结单时间 is not null 语句。
------解决方案--------------------
个人认为,你可以把你的语句拆分一下,把
你这样的话,select SUM(i_本级盈亏) FROM T_代理报表 WHERE i_本级代理id=A.i_下级代理id AND i_结单时间 between @startsj AND @endjs类似这样的语句要重复执行好几次
------解决方案--------------------
试试下面的语句
SELECT 下级代理名 = (
SELECT TOP 1 i_用户名 FROM T_会员 WHERE i_用户id = A.i_下级代理id
)
, app.下级占成金额
, app.下级退佣金额
, app.下级赚佣金额
, app.下级盈亏
, app.本级交上级
, SUM(i_会员购买金额) AS 会员购买金额
, SUM(i_本级占成所得) AS 本级占成所得
, SUM(i_本级退佣金额) AS 本级退佣金额
, SUM(i_本级赚佣金额) AS 本级赚佣金额
我有一个表大概有5百万条数据,表结构大致如下:
id (int 类型,自增主键+聚集索引)
i_本级代理id (int 类型,非聚集索引)
i_下级代理id (int 类型,非聚集索引)
i_本级占成金额
.....其它字段略
i_结单时间 (datetime类型, 非聚集索引)
***************************************************
我的SQL语句如下(大致返回20条数据行,用时27秒)
declare @d datetime
set @d=getdate()
DECLARE @userid int
DECLARE @startsj datetime
DECLARE @endjs datetime
SET @userid =1
SET @startsj ='2011-03-31 00:00:00'
SET @endjs ='2015-03-31 00:00:00'
SELECT
下级代理名=(select top 1 i_用户名 FROM T_会员 WHERE i_用户id=A.i_下级代理id),
下级占成金额=(select SUM(i_本级占成所得) FROM T_代理报表 WHERE i_本级代理id=A.i_下级代理id AND i_结单时间 between @startsj AND @endjs),
下级退佣金额=(select SUM(i_本级退佣金额) FROM T_代理报表 WHERE i_本级代理id=A.i_下级代理id AND i_结单时间 between @startsj AND @endjs),
下级赚佣金额=(select SUM(i_本级赚佣金额) FROM T_代理报表 WHERE i_本级代理id=A.i_下级代理id AND i_结单时间 between @startsj AND @endjs),
下级盈亏=(select SUM(i_本级盈亏) FROM T_代理报表 WHERE i_本级代理id=A.i_下级代理id AND i_结单时间 between @startsj AND @endjs),
本级交上级=(select SUM(i_本级交上级) FROM T_代理报表 WHERE i_本级代理id=A.i_下级代理id AND i_结单时间 between @startsj AND @endjs),
SUM(i_会员购买金额) AS 会员购买金额,
SUM(i_本级占成所得) AS 本级占成所得,
SUM(i_本级退佣金额) AS 本级退佣金额,
SUM(i_本级赚佣金额) AS 本级赚佣金额,
SUM(i_本级盈亏) AS 本级盈亏,
SUM(i_本级交上级) AS 本级交上级
FROM T_代理报表 A
WHERE A.i_本级代理id=@userid
AND (A.i_结单时间 between @startsj AND @endjs)
GROUP BY
A.i_本级代理id,
A.i_下级代理id
select [语句执行花费时间(毫秒)]=datediff(ms,@d,getdate())
****************************************************
问题:
当我把【 (A.i_结单时间 between @startsj AND @endjs)】 条件去掉,测试只要2.3秒
也就是说,只要加了【i_结单时间 】字段查询,效率就慢了几十倍,但这个字段我是有加索引的。
如果说数据表太大导致慢也没道理,如果是数据量问题,应该没加这个条件会更慢
另外我这个表几乎每秒钟都在写入数据,不知道会不会跟这个有关系
------解决方案--------------------
并非索引问题,而是楼主sql 语句写法有问题——select 中不要嵌套查询了
------解决方案--------------------
改写SQL语句,另外set statistics io on/set statistics time on 看看结果 最好也能贴出来
------解决方案--------------------
A.i_结单时间 有没有null的情况,如果有 在where 条件 加 A.i_结单时间 is not null 语句。
------解决方案--------------------
个人认为,你可以把你的语句拆分一下,把
下级代理名=(select top 1 i_用户名 FROM T_会员 WHERE i_用户id=A.i_下级代理id),放到一个临时表中,然后再和后面的查询进行连接查询,试试。
下级占成金额=(select SUM(i_本级占成所得) FROM T_代理报表 WHERE i_本级代理id=A.i_下级代理id AND i_结单时间 between @startsj AND @endjs),
下级退佣金额=(select SUM(i_本级退佣金额) FROM T_代理报表 WHERE i_本级代理id=A.i_下级代理id AND i_结单时间 between @startsj AND @endjs),
下级赚佣金额=(select SUM(i_本级赚佣金额) FROM T_代理报表 WHERE i_本级代理id=A.i_下级代理id AND i_结单时间 between @startsj AND @endjs),
下级盈亏=(select SUM(i_本级盈亏) FROM T_代理报表 WHERE i_本级代理id=A.i_下级代理id AND i_结单时间 between @startsj AND @endjs),
本级交上级=(select SUM(i_本级交上级) FROM T_代理报表 WHERE i_本级代理id=A.i_下级代理id AND i_结单时间 between @startsj AND @endjs),
你这样的话,select SUM(i_本级盈亏) FROM T_代理报表 WHERE i_本级代理id=A.i_下级代理id AND i_结单时间 between @startsj AND @endjs类似这样的语句要重复执行好几次
------解决方案--------------------
试试下面的语句
SELECT 下级代理名 = (
SELECT TOP 1 i_用户名 FROM T_会员 WHERE i_用户id = A.i_下级代理id
)
, app.下级占成金额
, app.下级退佣金额
, app.下级赚佣金额
, app.下级盈亏
, app.本级交上级
, SUM(i_会员购买金额) AS 会员购买金额
, SUM(i_本级占成所得) AS 本级占成所得
, SUM(i_本级退佣金额) AS 本级退佣金额
, SUM(i_本级赚佣金额) AS 本级赚佣金额