Hai*_*ood 4 php mysql optimization
所以我有一个看起来像这样的查询:
SELECT col1, col2, col3 ...
FROM action_6_members m
LEFT JOIN action_6_5pts f ON f.member_id = m.id
LEFT JOIN action_6_10pts t ON t.member_id = m.id
LEFT JOIN action_6_weekly w ON w.member_id = m.id
WHERE `draw_id` = '1' ORDER BY m.id DESC LIMIT 0, 20;
Run Code Online (Sandbox Code Playgroud)
现在这是一个大规模的加入(350万*4万*2万)
所以我的想法是:
做SELECT * FROM action_6_members WHEREdraw_id= '1' ORDER BY id DESC LIMIT 0, 20;
然后循环使用php来构建
$in = "IN(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)";
然后运行
select * from action_6_5pts where member_id in $in
select * from action_6_10pts where member_id in $in
select * from action_6_weekly where member_id in $in
然后使用php将它们全部一起刷,
这意味着,虽然我使用四种不同的查询,但我只从每个查询中选择20行,而不是在所有查询中进行连接.
我会注意到一个重要的绩效奖金吗?
这是应用程序的一般概述
它收到一个代码,
代码是5pt,10pt或每周代码,
所有三种代码类型都在单独的表中.这三个表有代码和member_id
member_id链接到action_6_members表中的id.
当声明代码时,数据被填入action_6_members表中.
然后该成员的ID被填充在表中对于被要求保护的代码.
上面的查询选择前20个成员.
所以我的问题是.
我该怎么做才能改善这一点?
因为目前所有内容都在查询完成之前超时.
action_6_members
CREATE TABLE `action_6_members` (
`id` int(11) NOT NULL auto_increment,
`draw_id` int(11) NOT NULL,
`mobile` varchar(255) NOT NULL,
`fly_buys` varchar(255) NOT NULL,
`signup_date` datetime NOT NULL,
`club` int(11) NOT NULL default '0' COMMENT '1 = yes, 2 = no',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1337 DEFAULT CHARSET=latin1
Run Code Online (Sandbox Code Playgroud)
action_6_ 5和10pts
CREATE TABLE `action_6_5pts` (
`code` varchar(255) NOT NULL,
`member_id` int(11) NOT NULL,
PRIMARY KEY (`code`),
KEY `member_id` (`member_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
Run Code Online (Sandbox Code Playgroud)
action_6_weekly
CREATE TABLE `action_6_weekly` (
`id` int(11) NOT NULL auto_increment,
`code` varchar(255) NOT NULL,
`member_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
KEY `member_id` (`member_id`)
) ENGINE=MyISAM AUTO_INCREMENT=3250001 DEFAULT CHARSET=latin1
Run Code Online (Sandbox Code Playgroud)
id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE m ALL \N \N \N \N 1390 Using temporary; Using filesort 1 SIMPLE f ALL member_id \N \N \N 36000 1 SIMPLE t ALL member_id \N \N \N 18000 Using where 1 SIMPLE w ref member_id member_id 4 m.id 525820 Using where
最新加载数据从DB 7.26,4.60,2.45:刚刚经历过这样的
1.0是正常的最大负载......任何上述意味着它必须"爆发"并调用其他进程来处理.即7.26表示负载是刀片服务器最大值的7倍,并且不得不呼叫其他人来帮忙
所以目前这个查询不仅仅是一个怪物,它吃怪物作为小吃......
作为一般规则,如果您的SQL查询可以完全模拟您想要做的事情,那么它可能比在特定范围内将其拆分为以PHP(或任何其他语言)粘合在一起的部分更快.
这些界限是:
max_allowed_packetin 的大小my.cnf).现在,这并没有解决您的SQL(或PHP中提议的替代实现)是否适合您正在做的事情,但只有在有关您的应用程序的功能以及您实际尝试的终点的更多信息时才能解决这个问题.到达.它可能没问题,也可能没有.
通过表格结构快速浏览一下您的更新,没有任何事情可以解决我可能造成大型性能问题的原因,但是:
action_6_weekly有id作为PRIMARY KEY,以及UNIQUE KEY对... id.这是多余的.PRIMARY KEY实际上是一个超集UNIQUE KEY,你不需要创建一个单独的UNIQUE KEY.EXPLAIN查询的输出会很有趣.