全球主机交流论坛

标题: 懂MYSQL的进来,索引的问题 [打印本页]

作者: soey    时间: 2013-12-13 09:13
标题: 懂MYSQL的进来,索引的问题
total = $db->fetchOne("SELECT count(doye) FROM `members`");
smarty->assign("total", $total);

这是程序的调用语句

每次打开网站,就执行一次上面的命令,每次打开统计一次,网站会员十几万,MYSQL吃CPU非常的厉害

有什么办法可以降低CPU的占用吗?

在网上搜索了一下,索引,就是为DOYE这个字段建立一个索引

问题出来了,建立索引后程序的调用语句是否需要更改

网上看到的建立索引的命令
CREATE INDEX ind_accountcode ON callhistory (accountcode);
我的应该是不是就应该这样写
CREATE INDEX ind total ON members (doye);
这条命令在MYSQL执行一次就可以了,还是要如何弄,求高手解答。
另外优化MYSQL还有什么比较好的建议吗?





作者: leassy    时间: 2013-12-13 09:19
本帖最后由 leassy 于 2013-12-13 09:20 编辑

ALTER TABLE `members` ADD INDEX `index_doye` (`doye`);
执行这个就好
作者: soey    时间: 2013-12-13 09:22
leassy 发表于 2013-12-13 09:19
ALTER TABLE `members` ADD INDEX `index_doye` (`doye`);
执行这个就好

这条命令是建立索引吗?
作者: leassy    时间: 2013-12-13 09:24
soey 发表于 2013-12-13 09:22
这条命令是建立索引吗?


作者: soey    时间: 2013-12-13 09:25
leassy 发表于 2013-12-13 09:24

程序中调用不变吗?
作者: ohmyga    时间: 2013-12-13 09:30
具体要同用explain 查看索引加哪上

"SELECT count(doye) FROM `members`"
"SELECT count(*) FROM `members`"
"SELECT count(1) FROM `members`"
"SELECT count(2) FROM `members`"

他们的效果都是一样的,那么多字段,你确定索引就加在 doye 上?
作者: soey    时间: 2013-12-13 09:36
ohmyga 发表于 2013-12-13 09:30
具体要同用explain 查看索引加哪上

"SELECT count(doye) FROM `members`"

其实我是想这样的
在数据库A中,有一个表MEMBERS,MEMBERS中有一个字段doye
上面是程序调用语句在PHP中你也看到了,这个语句,每有一个人打开网站,就执行一次,网站会员接近15万,每次打开执行一次那一个求和,15万每次耗费大量的CPU
就是想优化一下,或者加个命令,让PHP中执行的这个多长时间执行一次或者建立索引
作者: leassy    时间: 2013-12-13 09:46
soey 发表于 2013-12-13 09:25
程序中调用不变吗?

不用变
作者: ohmyga    时间: 2013-12-13 09:50
我认为这个语句不会耗费CPU 。
首先:
像count 语句本身就是高效的。如Discuz X3 会员表有70W记录 在一台普通PC上 速度是0.02xs左右,所以该语句不会成为瓶颈。

其次:如果使用myisam引擎 该语句还会保存记录的总数,直接返回结果,无需每次遍历,而不会像innodb一样还需要全表扫描一次。

你可以在phpmyadmin中执行  EXPLAIN SELECT count(doye) FROM `members`

如果Extra自动 出现 Select tables optimized away 完全没必要组任何东西。

(, 下载次数: 2)

而且就是个计算总数而已,打不了用php写个缓存啦。。
作者: leassy    时间: 2013-12-13 09:50
你的表引擎是什么,如果是MYISAM,那么不用加索引直接count都会很快
如果表引擎是InooDB,那么没什么好的办法,只能建议你count主键了,这个主键一般都是ID列吧


你试试 SELECT count(`id`) FROM `members`

这个id是你的主键字段,你看看你表中主键是哪个,就写上
作者: soey    时间: 2013-12-13 10:09
ohmyga 发表于 2013-12-13 09:50
我认为这个语句不会耗费CPU 。
首先:
像count 语句本身就是高效的。如Discuz X3 会员表有70W记录 在一台普 ...

id
select_type
table
type
possible_keys
key
key_len
ref
rows
Extra
1
SIMPLE
NULL
NULL
NULL
NULL
NULL
NULL
NULL
Select tables optimized away


直接COUNT会更快吗?
作者: soey    时间: 2013-12-13 10:10
ohmyga 发表于 2013-12-13 09:50
我认为这个语句不会耗费CPU 。
首先:
像count 语句本身就是高效的。如Discuz X3 会员表有70W记录 在一台普 ...

怎么看使用了myisam,我的是DIRECTADMIN
作者: soey    时间: 2013-12-13 10:11
leassy 发表于 2013-12-13 09:50
你的表引擎是什么,如果是MYISAM,那么不用加索引直接count都会很快
如果表引擎是InooDB,那么没什么好的办法, ...

嗯,谢谢
作者: ohmyga    时间: 2013-12-13 10:15
soey 发表于 2013-12-13 10:10
怎么看使用了myisam,我的是DIRECTADMIN

不用看了 你的是 myisam   那个查询速度很快的, 出现  Select tables optimized away  说的在俗点 表示已经不能再优化了,非常好了
作者: soey    时间: 2013-12-13 10:17
ohmyga 发表于 2013-12-13 10:15
不用看了 你的是 myisam   那个查询速度很快的, 出现  Select tables optimized away  说的在俗点 表示 ...

嗯,非常感谢!
作者: xuebook    时间: 2013-12-13 10:20
不懂
作者: cpuer    时间: 2013-12-13 10:31
soey 发表于 2013-12-13 10:10
怎么看使用了myisam,我的是DIRECTADMIN

现在大部分的都是myisam了,inooDB基本退出现在的舞台了
作者: leassy    时间: 2013-12-13 10:39
cpuer 发表于 2013-12-13 10:31
现在大部分的都是myisam了,inooDB基本退出现在的舞台了

也不能这样说,这要看这个表的使用力度和范围
如果这个表经常用于查询,很少用于写入和修改,那么就用myisam
如果用于写入和修改多于查询,那么则要用inooDB,这样性能会提高不少
作者: soey    时间: 2013-12-13 10:49
ohmyga 发表于 2013-12-13 10:15
不用看了 你的是 myisam   那个查询速度很快的, 出现  Select tables optimized away  说的在俗点 表示 ...

原来看错了
Cpu(s): 10.7%us,  1.6%sy,  0.0%ni, 87.7%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st

把87.7%id 看成使用的CPU了,其实是空闲的CPU

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND

TOP里面  %CPU 这个是什么,有时升到500%多

作者: ahao358    时间: 2013-12-13 10:51
其实可以建一个表,建一些字段专门存储这些信息,如楼主说的会员总数,增加会员时在那字段+1,读时直接读那字段:)
作者: soey    时间: 2013-12-13 10:52
ahao358 发表于 2013-12-13 10:51
其实可以建一个表,建一些字段专门存储这些信息,如楼主说的会员总数,增加会员时在那字段+1,读时直接读那 ...

那个数不是会员总数,而且那个数每时每刻都是变化的,建表是不合适的
作者: ahao358    时间: 2013-12-13 10:58
soey 发表于 2013-12-13 10:52
那个数不是会员总数,而且那个数每时每刻都是变化的,建表是不合适的

那个是做什么用的?根据不同作用、情况的不同可以做相应处理。
可以建立一缓存,写时更新缓存,读时直接读取缓内容,在读操作比写操作频繁时这样用起来还是有效率的。
或者其他人有更好的解决方法?
作者: soey    时间: 2013-12-13 11:02
ahao358 发表于 2013-12-13 10:58
那个是做什么用的?根据不同作用、情况的不同可以做相应处理。
可以建立一缓存,写时更新缓存,读时直接 ...

统计会员帐户余额的,余额每秒都在变的
作者: soey    时间: 2013-12-13 11:06
ahao358 发表于 2013-12-13 10:58
那个是做什么用的?根据不同作用、情况的不同可以做相应处理。
可以建立一缓存,写时更新缓存,读时直接 ...

如果跳过是0.00的话加个条件怎么写呢后面
作者: ahao358    时间: 2013-12-13 11:27
soey 发表于 2013-12-13 11:06
如果跳过是0.00的话加个条件怎么写呢后面

久没弄了,以前主要弄SQLITE,应该后面加入:
WHERE doye>0

具体可以参考MYSQL和SQL的语法:)
作者: ahao358    时间: 2013-12-13 11:30
soey 发表于 2013-12-13 11:02
统计会员帐户余额的,余额每秒都在变的

另外问下,你是统计单个会员的帐户余额还是所有会员?
作者: soey    时间: 2013-12-13 11:31
ahao358 发表于 2013-12-13 11:30
另外问下,你是统计单个会员的帐户余额还是所有会员?

所有的会员
作者: ahao358    时间: 2013-12-13 11:34
本帖最后由 ahao358 于 2013-12-13 11:38 编辑
soey 发表于 2013-12-13 11:31
所有的会员


什么东西那么流B,可以找些网赚程序来参考下,PTP、PTC等之类的应该会有相应的功能实现。
如果对余额数要求不严格,可以建一表和字段专门保存,当涉及金额变化时可以对改字段做相应的加减,不过只对读有效率,对写没什么优势。




欢迎光临 全球主机交流论坛 (https://d.168530.xyz/) Powered by Discuz! X3.4