Php 优化查询

Php 优化查询,php,mysql,Php,Mysql,希望您能帮助我们使用索引(或者查询本身)优化MySQL查询 表结构: CREATE TABLE IF NOT EXISTS `match_current` ( `partnership_id` int(11) NOT NULL AUTO_INCREMENT, `runs` int(5) NOT NULL DEFAULT '0', `balls` int(5) NOT NULL DEFAULT '0', `user1_id` bigint(11) NOT NULL, `user

希望您能帮助我们使用索引(或者查询本身)优化MySQL查询

表结构:

CREATE TABLE IF NOT EXISTS `match_current` (
  `partnership_id` int(11) NOT NULL AUTO_INCREMENT,
  `runs` int(5) NOT NULL DEFAULT '0',
  `balls` int(5) NOT NULL DEFAULT '0',
  `user1_id` bigint(11) NOT NULL,
  `user1_firstname` char(20) NOT NULL,
  `user1_lastname` char(20) NOT NULL,
  `user1_runs` int(5) NOT NULL DEFAULT '0',
  `user1_balls` int(5) NOT NULL DEFAULT '0',
  `user1_strike` tinyint(1) NOT NULL DEFAULT '1',
  `user1_out` tinyint(1) NOT NULL DEFAULT '0',
  `user1_retired` tinyint(1) NOT NULL DEFAULT '0',
  `user2_id` bigint(11) NOT NULL,
  `user2_firstname` char(20) NOT NULL,
  `user2_lastname` char(20) NOT NULL,
  `user2_runs` int(5) NOT NULL DEFAULT '0',
  `user2_balls` int(5) NOT NULL DEFAULT '0',
  `user2_strike` tinyint(1) NOT NULL DEFAULT '0',
  `user2_out` tinyint(1) NOT NULL DEFAULT '0',
  `user2_retired` tinyint(1) NOT NULL DEFAULT '0',
  `last_over` char(15) NOT NULL,
  `ball_by_ball` varchar(1000) NOT NULL,
  `facebook` tinyint(1) NOT NULL DEFAULT '0',
  `friends` tinyint(1) NOT NULL DEFAULT '0',
  `nudge` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `started` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `status` tinyint(1) NOT NULL DEFAULT '1',
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`partnership_id`),
  UNIQUE KEY `user1_id_2` (`user1_id`,`user2_id`,`facebook`),
  KEY `user2_id` (`user2_id`),
  KEY `user1_id` (`user1_id`),
  KEY `facebook` (`facebook`),
  KEY `status` (`status`),
  KEY `friends` (`friends`),
  KEY `timestamp` (`timestamp`),
  KEY `user1_id_3` (`user1_id`,`user1_strike`),
  KEY `user2_id_2` (`user2_id`,`user2_strike`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=36139 ;
示例查询:

SELECT * 
FROM match
WHERE status = 1 
AND (
  (user1_id=1234 AND user1_strike=1) OR 
  (user2_id=4321 AND user2_strike=1)
) 
ORDER BY timestamp ASC
很明显,这个查询很有效,做得也不算太差,但最近我们的流量真的增加了,现在我看到它开始挣扎了


干杯

你真的需要一切吗

SELECT *
为WHERE子句创建索引

INDEX(user1_id, user1_strike, user2_id, user2_strike)
您还可以在索引中包含TimeTemp并将排序设置为ASC


除此之外,数据库的表可能还需要额外的索引和重新设计。还考虑检查SQL Server设置(使用NYNDB表,并为服务器设置正确的缓存/内存限制)。在优化查询时要记住的一件事是MySQL在执行查询时只选择一个索引;盲目地为您能想到的任何字段组合编制索引可能没有多大帮助,事实上会减慢插入速度

这看起来像一个典型的表,由两名玩家组成一个团队,因此,由于您不确定被查询的用户是在
user1
还是
user2
中,因此您将搜索这两个用户。这很可能导致拒绝所有键,并因此执行表扫描

我的建议是稍微去规范化您的表,并创建一个单独的表,在其中存储
(用户id,合作伙伴id)
,再加上一个扩展主键,
partnerships
中的每个记录都是该表中的两个记录;这消除了
,您可以使用简单的
连接
从较大的表中获取所需的信息


为了帮助您调查这些问题,您可以使用
EXPLAIN
查看MySQL是如何“攻击”您的查询的。

为了优化查询,人们还需要知道表结构/索引是什么。考虑添加<代码>的输出,显示“创建表匹配< /代码>”到您的问题。您想在哪些列上设置索引?索引用于字符串匹配和搜索,而不是数字或日期时间列…您需要向我们展示您拥有的索引。首先想到的是,您是否真的需要表中的所有内容(即
SELECT*
)?在这种情况下,它可能不会影响性能,但是,列出所选字段可以使代码更具可读性,因为其他员工不必检查模式来了解您实际选择的内容。