优化 MySQL 语句的十个建议(2)
发布时间:2012-05-08 07:14:36
5.不要过度使用artificial primary key
artificial primary key非常棒,因为他们使得schema更少的变化。如果我们将地理信息存在以美国邮编为基础的表中,如果邮编系统突然改变了,那我们就会有 * 烦了。另 一方面,采用natural key有时候也很棒,譬如我们需要join多对多的关系表时,我们不应该这样:
CREATE TABLE posts_tags (
relation_id int UNSIGNED NOT NULL AUTO_INCREMENT,
post_id int UNSIGNED NOT NULL,
tag_id int UNSIGNED NOT NULL,
PRIMARY KEY(relation_id),
UNIQUE INDEX(post_id, tag_id)
);
artificial key完全是多余的,而且post-tag关系的数量将会受到整形数据的系统最大值的限制。
CREATE TABLE posts_tags (
post_id int UNSIGNED NOT NULL,
tag_id int UNSIGNED NOT NULL,
PRIMARY KEY(post_id, tag_id)
);
6.学习索引
你选择的索引的好坏很重要,不好的话可能破坏数据库。对那些还没有在数据库学习很深入的人来说,索引可以看作是就是hash排序。例如如果我们用查询语句SELECT * FROM users WHERE last_name = ‘Goldstein’,而last_name没有索引的话,那么DBMS将会查询每一行,看看是否等于“Goldstein”。索引通常是B-tree(还有其他的类型),可以加快比较的速度。
你需要给你要select,group,order,join的列加上索引。显然每个索引所需的空间正比于表的行数,所以越多的索引将会占用更多的 内存。而且写数据时,索引也会有影响,因为每次写数据时都会更新对应的索引。你需要取一个平衡点,取决每个系统和实施代码的需要。
7.SQL不是C
C是经典的过程语言,对于一个程序员来说,C语言也是个陷阱,使你错误的以为SQL也是一种过程语言(当然SQL也不是功能语言也不是面向对象的)。你不要想象对数据进行操作,而是要想象有一组数据,以及它们之间的关系。经常使用子查询时会出现错误的用法。
SELECT a.id,
(SELECT MAX(created)
FROM posts
WHERE author_id = a.id)
AS latest_post
FROM authors a
因为这个子查询是耦合的,子查询要使用外部查询的信息,我们应该使用join来代替。
SELECT a.id, MAX(p.created) AS latest_post
FROM authors a
INNER JOIN posts p
ON (a.id = p.author_id)
GROUP BY a.id
8.理解你的引擎
MySQL有两种存储引擎:MyISAM和InnoDB。它们分别有自己的性能特点和考虑因素。总体来讲,MyISAM适合读数据很多的情况,InnoDB适合写数据很多的情况,但也有很多情况下正好相反。最大的区别是它们如何处理COUNT函数。
MyISAM缓存有表meta-data,如行数。这就意味着,COUNT(*)对于一个结构很好的查询是不需要消耗多少资源的。然后对于 InnoDB来说,就没有这种缓存。举个例子,我们要对一个查询来分页,假设你有这样一个语句SELECT * FROM users LIMIT 5,10,而运行SELECT COUNT(*) FROM users LIMIT 5,10 时,对于MyISAM很快完成,而对InnoDB就需要和第一个语句相同的时间。MySQL有个SQL_CALC_FOUND_ROWS选项,可以告诉 InnoDB运行查询语句时就计算行数,之后再从SELECT FOUND_ROWS()来获取。这是MySQL特有的。但使用InnoDB有时候是非常必要的,你可以获得一些功能(如行锁定,stord procedure等)。
9.MySQL特定的快捷键
MySQL提供了许多扩展,方便使用。譬如INSERT … SELECT, INSERT … ON DUPLICATE KEY UPDATE, 以及REPLACE。
我能用到它们时是毫不犹豫的,因为它们很方便,能在许多情况下发挥不错的效果。但是MySQL也有一些危险的关键字,应该少用。例如INSERT DELAYED,它告诉MySQL不需要立即插入数据(例如在写日志的时候)。但问题是如果在很高数据量的情况下,插入可能会被无限期延迟,导致插入队列 爆满。你也可以使用MySQL的索引提示来指出哪些索引是需要使用的。MySQL大部分时间运行是不错的,但如果schema设计不好的话或语句写得不好 的话,MySQL的表现可能很糟糕。
10.到这里为止吧
最后,如果你关心MySQL性能优化的话,请阅读Peter Zaitsev的关于MySQL性能的博客,他写了许多关于数据库管理和优化的博客。


猜你喜欢
- python中的paramiko模块是用来实现ssh连接到远程服务器上的库,在进行连接的时候,可以用来执行命令,也可以用来上传文件。1、得到
- MaxDB是MySQL AB公司通过SAP认证的数据库。MaxDB数据库服务器补充了MySQL AB产品系列。某些MaxDB特性在MySQL
- python 3.10支持match语句,3,10以下不支持。match语句接受一个表达式,并将其值与作为一个或多个case块给出的连续模式
- 1. 一个指令定义对象可以提供如下几个钩子函数(均为可选)bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置
- 本文转自微信公众号:"算法与编程之美",一、问题描述在collections模块中的defauldict使用时与dict
- 均方损失函数:这里 loss, x, y 的维度是一样的,可以是向量或者矩阵,i 是下标。很多的 loss 函数都有 size_averag
- 前言xml课的第三第四个作业都是用java编程来实现xml dom的一些转换, 因为自己没怎么学过java,因此和老师说了下想用python
- 代码很简洁,也很简单,就不多废话了。/** * 去除多余的0 */ function del0($s)&
- 作者:Robert Lair and Jason Lefebvr Intensity Software, Inc.
- 本文实例讲述了微信小程序module.exports模块化操作。分享给大家供大家参考,具体如下:文件 目录如上图:看到网上写的模块化都比较复
- 每当重大节日期间,各大主流网站首页会披上节日的盛装,设计者一般会使用大幅背景图片来获得更好的视觉冲击效果,当然,也要考虑到有些用户不习惯这大
- 一、概述python中的逻辑操作符and 和or,也叫惰性求值,由于是惰性,只要确定了值就不往后解析代码了。二、用法说明(一)and 用法文
- 汉字转换为UTF-8的一段代码终于找到这段代码了,一个ASP写的中文转UTF-8,大家可以试试function chinese2u
- 写的dht协议搜索的程序,这几天优化了一下发现速度确实快了好多。但是出现了一个新的问题,内存直接飙升,我开了十个爬虫占用内存800m。开始我
- 用Python随机生成学生姓名,三科成绩和班级数据,再插入到PostgreSQL中。模块用psycopg2 randomimport ran
- 一 、MySQL版本查询1)登录mysql首先Window+R然后在命令行里输入mysql -u此处填你的mysql账号(注意要加-u) -
- 问题描述尝试用Python写一个Wordcloud的时候,出现了编码问题。照着网上某些博客的说法添添改改后,结果是变成了“UnicodeDe
- 测试数据 http://grouplens.org/datasets/movielens/协同过滤推荐算法主要分为:1、基于用户。根据相邻用
- 在SQL Server 2005中,它的另外一个强大的新特点是数据库快照。数据库快照是一个数据库的只读副本,它是数据库所有数据的映射,由快照
- 这篇博客将介绍如何使用OpenCV制作Mask图像掩码。使用位运算和图像掩码允许我们只关注图像中感兴趣的部分,截取出任意区域的ROIs。应用