mysql - 表和查询优化

标签 mysql select optimization

简单的网络应用程序,使用 PHP 和 MySql 后端托管在标准共享托管上。

我有两个相对较小的表(每个表只有几百行),当我使用联接进行查询时,查询可能需要两到三秒的时间。

这是一张表:“学生”:

CREATE TABLE IF NOT EXISTS `students` (
`_id` mediumint(9) NOT NULL AUTO_INCREMENT,
  `firstname` char(30) NOT NULL,
  `lastname` char(30) NOT NULL,
  `dateOfBirth` date DEFAULT NULL,
  `gender` varchar(10) NOT NULL,
  `knownasname` varchar(30) NOT NULL,
  `school` varchar(30) DEFAULT NULL,
  `schoolyear` varchar(30) DEFAULT NULL,
  `notes` text,
  `foundusvia` varchar(30) DEFAULT NULL,
  `dateadded` datetime NOT NULL,
  `archived` tinyint(1) DEFAULT NULL,
  PRIMARY KEY (`_id`),
  UNIQUE KEY `_id` (`_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=684 ;

这是第二个:

CREATE TABLE IF NOT EXISTS `contacts` (
  `_id` mediumint(9) NOT NULL AUTO_INCREMENT,
  `student_id` mediumint(9) NOT NULL,
  `studentAddressStreet` varchar(50) DEFAULT NULL,
  `studentAddressArea` varchar(30) DEFAULT NULL,
  `studentAddressTown` varchar(30) DEFAULT NULL,
  `studentAddressPostcode` varchar(30) DEFAULT NULL,
  `studentPhoneMobile` varchar(30) DEFAULT NULL,
  `studentPhoneLand` varchar(30) DEFAULT NULL,
  `studentAddressNotes` text,
  `studentemail` varchar(50) DEFAULT NULL,
  `billingAddressStreet` varchar(50) DEFAULT NULL,
  `billingAddressArea` varchar(30) DEFAULT NULL,
  `billingAddressTown` varchar(30) DEFAULT NULL,
  `billingAddressPostcode` varchar(30) DEFAULT NULL,
  `billingPhoneMobile` varchar(30) DEFAULT NULL,
  `billingPhoneLand` varchar(30) DEFAULT NULL,
  `billingContactName` varchar(30) DEFAULT NULL,
  `billingContactRelationship` varchar(30) DEFAULT NULL,
  `billingAddressNotes` text,
  `billingemail` varchar(50) DEFAULT NULL,
  `caregiverAddressStreet` varchar(50) DEFAULT NULL,
  `caregiverAddressArea` varchar(30) DEFAULT NULL,
  `caregiverAddressTown` varchar(30) DEFAULT NULL,
  `caregiverAddressPostcode` varchar(30) DEFAULT NULL,
  `caregiverPhoneMobile` varchar(30) DEFAULT NULL,
  `caregiverPhoneLand` varchar(30) DEFAULT NULL,
  `caregiverContactName` varchar(30) DEFAULT NULL,
  `caregiverContactRelationship` varchar(30) DEFAULT NULL,
  `caregiverAddressNotes` text,
  `caregiveremail` varchar(50) DEFAULT NULL,
    PRIMARY KEY (`_id`),
  KEY `contacts_index` (`student_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=290 ;

这是查询:

它的工作是从表“students”和“contacts”中获取具有给定 _id 的学生的所有数据。

SELECT * 
  FROM students, contacts
 WHERE students._id = contacts.student_id
  AND students._id =99  <=== This value obviously changes

contacts有一个关于student_id的索引

学生表有一个关于名字和姓氏的索引。

导致此查询需要 2 到 3 秒才能运行有什么问题?表很小,查询也很简单。非常感谢任何帮助!!

编辑:这是 EXPLAIN 的输出。还修改了联系人表的 CREATE

id | select_type | table   | type | possible_keys | key          | key_len | ref  | rows | Extra
===|=============|=========|======|===============|==============|=========|======|=============
1  |  SIMPLE     | students|const | PRIMARY       | PRIMARY      |  3      |const | 1    |
1  |  SIMPLE     | contacts|ref   | contacts_index|contacts_index|  3      |const | 1    |

最佳答案

专业提示:如果可能,请避免 SELECT *。这在 JOIN 上尤其成问题。

如果您使用标准 JOIN,就像这样,您将可以更轻松地阅读查询。以逗号分隔的表列表 jumped the shark 20 世纪 90 年代末的某个时候。

SELECT students.*, 
       contacts.* 
  FROM students
  LEFT JOIN contacts ON students._id = contacts.student_id
 WHERE students._id =99 

最后,在 contacts 表的 student_id 列上放置一个索引,以便联接可以快速访问该表。

关于mysql - 表和查询优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28933527/

相关文章:

swift - 为什么 Swift 在 for-in 循环中使用下标语法比直接访问元素更快?

mysql - 在 MySQL 中使用哪种文本数据类型是正确的?

mysql - 嵌套集模型维护

php - 如何将 MySQL 中的 id 添加到 session cookie

Mysql 选择带有计数的查询

matlab - 使用 MATLAB 的 GPU 功能计算 sum(a.*exp(b.*c),1) 的有效方法

MYSQL 查询优化 - 连接/联合与表查询

css - firefox 不垂直居中选择指定高度的输入内容

C套接字编程: client send() but server select() doesn't see it

C++:如果所有数据可能已经有效,是否存在在构造函数中进行验证的开销?