mysql select count并发_关于select Count()的使用和性能问题

比如Count(*) FROM E_Table WHERE [date] > '2008-1-1' AND istrue = 0

由于操作的数据比较大(400万以上),所以使用了两个数据库,一个用于更新,执行频繁的Insert、Update操作,把索引建在了主键id上,另一个数据库定时复制前一个数据库的数据,用于检索查询,在[date]字段上建立了聚簇索引,在[istrue]字段上建立了非聚簇索引。这样下来,每次Count花费不超过2s的时间。

后来又复制了一份数据库,做了一些字段的调整,其中istrue字段被删除,非聚簇索引也去除了,而[date]字段和聚簇索引没有变动。

结果在执行Count(*) FROM E_Table WHERE [date] > '2008-1-1'的时候,却出现了奇怪的现象,原本以为会更快完成的检索(因为表的条数有减少),反而花费了30+s。

反复检查两个表,没有发现除了非聚簇索引外的不同,又测试在前一个表上执行相同的Count(*) FROM E_Table WHERE [date] > '2008-1-1',花费时间在1s左右。

只好把非聚簇索引和istrue字段加上,结果检索速度立刻回到1s!

一个在检索条件中不出现的字段为什么会影响检索的效率呢?仔细对比两次的Excuting Plan,终于发现了问题所在:

花费30s的检索第一步:

caa3185da9ccc87eda2b95a95565287d.png

花费1s的检索第一步:

c7cb5c09f721cb0527957ab378b638d8.png

除了两者的操作不同(一般情况下,Clustered Index Seek的速度应该快于Index Scan),CPU Cost是近似的,Number of Rows是一样的,最大的差别在I/O Cost上,前者是后者的5倍!

究其原因,主要是因为SQL Server执行Count操作的策略。当建有索引时,而且Count的参数是*或者Not Null类型的字段时,SQL Server会对所有索引列中体积最小的索引进行Scan。而istrue字段是bit类型的,只占1个字节,[date]字段是smalldatetime类型的,占4个字节。检索前者的I/O自然远远小于检索后者的,在同样的内存条件下,通过前者检索花费的时间也要远小于后者。

当然,如果Count的参数是某个Null类型的字段,SQL Server则只能对该字段进行Scan,因为这时该字段为Null的记录不记录的。所以,一个优化建议是,尽量少用Null类型字段,使用默认值+bit类型的索引字段会提高Count检索的效率。

另外:关于where条件

COUNT时的WHERE

简单说下,就是COUNT的时候,如果没有WHERE限制的话,MySQL直接返回保存有总的行数

而在有WHERE限制的情况下,总是需要对MySQL进行全表遍历。

优化总结:

1.任何情况下SELECT COUNT(*) FROM tablename是最优选择;

2.尽量减少SELECT COUNT(*) FROM tablename WHERE COL = ‘value’ 这种查询;

3.杜绝SELECT COUNT(COL) FROM tablename WHERE COL2 = ‘value’ 的出现。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL 中,可以使用触发器实现并发控制。触发器是一段存储过程,当某个特定事件发生时,MySQL 自动执行该存储过程。通过在触发器中编写逻辑代码,可以实现对并发操作的控制。 以下是一个示例,演示如何使用触发器实现并发控制: 假设有一个表 `users`,其中包含用户信息。我们希望每个用户的用户名都是唯一的。为了实现这一点,我们可以创建一个名为 `unique_username` 的触发器,以确保每次插入或更新操作都不会导致重复的用户名。具体步骤如下: 1. 创建触发器 ```sql CREATE TRIGGER unique_username BEFORE INSERT ON users FOR EACH ROW BEGIN DECLARE count INT; SELECT COUNT(*) INTO count FROM users WHERE username = NEW.username; IF count > 0 THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Username already exists'; END IF; END; ``` 2. 测试触发器 现在,无论是插入新用户还是更新现有用户的用户名,都会触发 `unique_username` 触发器。如果要插入的用户名已经存在,则会引发一个 SQLSTATE 为 '45000' 的错误。 例如,以下语句将尝试插入一个已经存在的用户名,从而触发触发器: ```sql INSERT INTO users (id, username) VALUES (1, 'john.doe'); ``` 执行该语句后,MySQL 将返回以下错误: ``` ERROR 1644 (45000): Username already exists ``` 这表明触发器已成功地阻止了插入操作,并确保了用户名的唯一性。 总之,通过使用 MySQL 中的触发器,可以实现并发控制,确保数据库中的数据保持一致性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值