请教SQL执行一条COUNT语句,如何提供高效率,降低CPU消耗。

MaWenDong 2015-01-28 09:25:34
select count(id) as count_id from [Table_APP_Data18] where [owner]=9429 and [app]=18 and [jiqi]=238


我的MSSQL是2005版,同时有2000个用户在频繁请求查询上面的语句,导致服务器CPU90%左右居高不下。

目前该表数据量100万+条。使用的是ASP方式,ASP程序每次连接后都有释放。

请问如何优化上面的语句?或如何解决CPUn消耗问题。

另外请教下面的语句写法会影响效率吗?

下面的owner、app、jiqi字段都是INT类型

select count(id) as count_id from [Table_APP_Data18] where [owner]='9429' and [app]='18' and [jiqi]='238'


select count(id) as count_id from [Table_APP_Data18] where [owner]=9429 and [app]=18 and [jiqi]=238
...全文
929 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
rfq 2015-04-24
  • 打赏
  • 举报
回复
go 首先你先看看 是什么原因导致了cpu 占有率 sql profiler 或者 select * from sys.dm_exec_query_stats go 如果是这个语句的问题。 执行计划 一般都是 编译一次缓存。不用在编译了。看是 因为重复编译 还是 语句 没有索引。 但是 我估计 不是编译的问题。 估计是内存不足,读取 数据 造成分页 的原因 。
hery2002 2015-04-22
  • 打赏
  • 举报
回复
做成存储过程传参数,使用第二种写法好,这样会重用执行计划,减少CPU的编译时间。 第一种写法下,执行计划会报隐式转换的报警,极端情况下,会导致你的索引失效。 如果app 和jiqi列的的最大值不大的情况下,可以考虑TINYINT,尽量缩短你的字段的类型长度,保证内存中可以存放更多的索引页,提高性能。
吉普赛的歌 2015-04-22
  • 打赏
  • 举报
回复
另外一种思路: 创建一个表, 只有一个字段, 只有一行。 if obect_id('t_count') is not null drop table t_count go create table t_count( id int ) go insert into t_count values(0) update t_count set id = ( select count(id) as count_id from [Table_APP_Data18] where [owner]='9429' and [app]='18' and [jiqi]='238' ) go 在 Table_APP_Data18 这个表上加一个触发器, 每当有 insert , update , delete 操作时, 对应更新 t_count 的值。 注: 如果这个表的增,删、改非常频繁, 应该只是根据条件让 t_count 的id值+或-; 如果不频繁, 可以根据sql语句来直接统计更新 t_count 的值。
生命沉思者 2015-04-22
  • 打赏
  • 举报
回复
引用 13 楼 kxjrzyk 的回复:
[owner] 、 [app] 建成组合索引,COUNT改成COUNT(*)
是[owner] 、 [app] 、[jiqi]建成组合索引,COUNT改成COUNT(*),少看了一个条件
生命沉思者 2015-04-22
  • 打赏
  • 举报
回复
[owner] 、 [app] 建成组合索引,COUNT改成COUNT(*)
吉普赛的歌 2015-02-04
  • 打赏
  • 举报
回复
引用 3 楼 thisisdell 的回复:
若只有一个字段,使用COUNT(*); 若有主键,使用COUNT(主键); 若没有主键,使用COUNT(1)。 我做大数据时,一般再建一个记录统计计数表,当数据表增加一条记录时,统计表计数也对应+1;数据表删除一条记录时,统计表计数也对应-1。在统计记录时,直接SELECT 统计表计数字段。
别搞这么复杂, 你把3种的执行计划贴出来看一下, 都是一样的
shiyiwan 2015-01-31
  • 打赏
  • 举报
回复
引用 3 楼 thisisdell 的回复:
若只有一个字段,使用COUNT(*); 若有主键,使用COUNT(主键); 若没有主键,使用COUNT(1)。 我做大数据时,一般再建一个记录统计计数表,当数据表增加一条记录时,统计表计数也对应+1;数据表删除一条记录时,统计表计数也对应-1。在统计记录时,直接SELECT 统计表计数字段。
以前有个误区任务count(*), count(1), count(PK)的效率是不一样的,不知道SQL server方面如何,Oracle中是无差别的。
shiyiwan 2015-01-31
  • 打赏
  • 举报
回复
100万条数据量并不大。 CPU占用居高不下应该不是没有索引的问题,当然加了索引会提高执行效率。 问题主要应该是在asp查询请求时,针对不同的owner, app值,服务器都需要做一次硬解析。不能够使用cache中已有的解析结果。 改asp的查询语句为绑定变量形式,提升效果应该会好。
yoan2014 2015-01-31
  • 打赏
  • 举报
回复
两种写法建议采用第二种,第一种需要进行一次参数的隐式转换,最好参数的类型要与查询的列类型一致,有些情况下还可能导致索引都失效
吉普赛的歌 2015-01-30
  • 打赏
  • 举报
回复
1. 给出完整表结构及测试数据; 2. 数据量大概多少? 3. 贴出执行计划图
MaWenDong 2015-01-30
  • 打赏
  • 举报
回复
引用 3 楼 thisisdell 的回复:
若只有一个字段,使用COUNT(*); 若有主键,使用COUNT(主键); 若没有主键,使用COUNT(1)。 我做大数据时,一般再建一个记录统计计数表,当数据表增加一条记录时,统计表计数也对应+1;数据表删除一条记录时,统计表计数也对应-1。在统计记录时,直接SELECT 统计表计数字段。
谢谢你的解答。这个表使用周期就半个月,感觉没必要单独用一个表做统计(加删都要写),既然MSSQL提供COUNT和索引等功能干什么用笨方法那。
MaWenDong 2015-01-30
  • 打赏
  • 举报
回复
引用 2 楼 guguda2008 的回复:
写法没问题,问题应该是没索引
谢谢,我已经增加索引。
Q315054403 2015-01-30
  • 打赏
  • 举报
回复
简单的用法是建视图索引(不记得2005是否支持了,2008及以上是支持的) 或者自己做聚合为实体表 再或者建个包含索引 不同场景,使用方法略有不同
薛定谔的DBA 2015-01-28
  • 打赏
  • 举报
回复
从语句看,消耗CPU的主要是编译,聚合计算。 可以定义一个存储过程,带入参数。 [owner]=@owner and [app]=@app] and [jiqi]=@app] 如果对统计不严格,可以使用nolock,或者查询sysindexes的rows 剩下的,加索引吧。 附加:字段的类型是什么就给什么样的值。给不同的类型的值系统会隐式转换,不仅耗CPU,索引页用不了
thisisdell 2015-01-28
  • 打赏
  • 举报
回复
若只有一个字段,使用COUNT(*); 若有主键,使用COUNT(主键); 若没有主键,使用COUNT(1)。 我做大数据时,一般再建一个记录统计计数表,当数据表增加一条记录时,统计表计数也对应+1;数据表删除一条记录时,统计表计数也对应-1。在统计记录时,直接SELECT 统计表计数字段。
guguda2008 2015-01-28
  • 打赏
  • 举报
回复
写法没问题,问题应该是没索引
guguda2008 2015-01-28
  • 打赏
  • 举报
回复
CREATE INDEX INX_Table_APP_Data18
ON [Table_APP_Data18]
([owner],[app],[jiqi])

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧