MySQL十大优化技巧详解

1、优化你的MySQL查询缓存

  在MySQL服务器上进行查询,可以启用高速查询缓存。让数据库引擎在后台悄悄的处理是提高性能的最有效方法之一。当同一个查询被执行多次时,如果结果是从缓存中提取,那是相当快的。

  但主要的问题是,它是那么容易被隐藏起来以至于我们大多数程序员会忽略它。在有些处理任务中,我们实际上是可以阻止查询缓存工作的。

// query cache does NOT work
$r = mysql_query("SELECT username FROM user WHERE signup_date >= CURDATE()");
// query cache works!
$today = date("Y-m-d");
$r = mysql_query("SELECT username FROM user WHERE signup_date >= ‘$today‘");

  2、用EXPLAIN使你的SELECT查询更加清晰

  使用EXPLAIN关键字是另一个MySQL优化技巧,可以让你了解MySQL正在进行什么样的查询操作,这可以帮助你发现瓶颈的所在,并显示出查询或表结构在哪里出了问题。

  EXPLAIN查询的结果,可以告诉你那些索引正在被引用,表是如何被扫描和排序的等等。

  实现一个SELECT查询(最好是比较复杂的一个,带joins方式的),在里面添加上你的关键词解释,在这里我们可以使用phpMyAdmin,他会告诉你表中的结果。举例来说,假如当我在执行joins时,正忘记往一个索引中添加列,EXPLAIN能帮助我找到问题的所在。

添加索引到group_id field后:

3、利用LIMIT 1取得唯一行

  有时,当你要查询一张表是,你知道自己只需要看一行。你可能会去的一条十分独特的记录,或者只是刚好检查了任何存在的记录数,他们都满足了你的WHERE子句。

  在这种情况下,增加一个LIMIT 1会令你的查询更加有效。这样数据库引擎发现只有1后将停止扫描,而不是去扫描整个表或索引。

// do I have any users from Alabama?
// what NOT to do:
$r = mysql_query("SELECT * FROM user WHERE state = ‘Alabama‘");
if (mysql_num_rows($r) > 0) {
// ...
}
// much better:
$r = mysql_query("SELECT 1 FROM user WHERE state = ‘Alabama‘ LIMIT 1");
if (mysql_num_rows($r) > 0) {
// ...
}

  4、索引中的检索字段

  索引不仅是主键或唯一键。如果你想搜索表中的任何列,你应该一直指向索引。

5、保证连接的索引是相同的类型

  如果应用程序中包含多个连接查询,你需要确保你链接的列在两边的表上都被索引。这会影响MySQL如何优化内部联接操作。

  此外,加入的列,必须是同一类型。例如,你加入一个DECIMAL列,而同时加入另一个表中的int列,MySQL将无法使用其中至少一个指标。即使字符编码必须同为字符串类型。

// looking for companies in my state
$r = mysql_query("SELECT company_name FROM users LEFT JOIN companies ON (users.state = companies.state) WHERE users.id = $user_id");
// both state columns should be indexed
// and they both should be the same type and character encoding
// or MySQL might do full table scans

6、不要使用BY RAND()命令

  这是一个令很多新手程序员会掉进去的陷阱。你可能不知不觉中制造了一个可怕的平静。这个陷阱在你是用BY RAND()命令时就开始创建了。

  如果您真的需要随机显示你的结果,有很多更好的途径去实现。诚然这需要写更多的代码,但是能避免性能瓶颈的出现。问题在于,MySQL可能会为表中每一个独立的行执行BY RAND()命令(这会消耗处理器的处理能力),然后给你仅仅返回一行。

// what NOT to do:
$r = mysql_query("SELECT username FROM user ORDER BY RAND() LIMIT 1");
// much better:
$r = mysql_query("SELECT count(*) FROM user");
$d = mysql_fetch_row($r);
$rand = mt_rand(0,$d[0] - 1);
$r = mysql_query("SELECT username FROM user LIMIT $rand, 1");

  7、尽量避免SELECT *命令

  从表中读取越多的数据,查询会变得更慢。他增加了磁盘需要操作的时间,还是在数据库服务器与WEB服务器是独立分开的情况下。你将会经历非常漫长的网络延迟,仅仅是因为数据不必要的在服务器之间传输。

  始终指定你需要的列,这是一个非常良好的习惯。

// not preferred
$r = mysql_query("SELECT * FROM user WHERE user_id = 1");
$d = mysql_fetch_assoc($r);
echo "Welcome {$d[‘username‘]}";
// better:
$r = mysql_query("SELECT username FROM user WHERE user_id = 1");
$d = mysql_fetch_assoc($r);
echo "Welcome {$d[‘username‘]}";
// the differences are more significant with bigger result sets

  8、从PROCEDURE ANALYSE()中获得建议

  PROCEDURE ANALYSE()可让MySQL的柱结构分析和表中的实际数据来给你一些建议。如果你的表中已经存在实际数据了,能为你的重大决策服务。

9、准备好的语句

  准备好的语句,可以从性能优化和安全两方面对大家有所帮助。

  准备好的语句在过滤已经绑定的变量默认情况下,能给应用程序以有效的保护,防止SQL注入攻击。当然你也可以手动过滤,不过由于大多数程序员健忘的性格,很难达到效果。

// create a prepared statement
if ($stmt = $mysqli->prepare("SELECT username FROM user WHERE state=?")) {
// bind parameters
$stmt->bind_param("s", $state);
// execute
$stmt->execute();
// bind result variables
$stmt->bind_result($username);
// fetch value
$stmt->fetch();
printf("%s is from %s\n", $username, $state);
$stmt->close();
}

  10、将IP地址存储为无符号整型

  许多程序员在创建一个VARCHAR(15)时并没有意识到他们可以将IP地址以整数形式来存储。当你有一个INT类型时,你只占用4个字节的空间,这是一个固定大小的领域。

  你必须确定你所操作的列是一个UNSIGNED INT类型的,因为IP地址将使用32位unsigned integer。

$r = "UPDATE users SET ip = INET_ATON(‘{$_SERVER[‘REMOTE_ADDR‘]}‘) WHERE user_id = $user_id";

介绍两个函数:

inet_aton()是一个改进的方法来将一个字符串IP地址转换为一个32位的网络序列IP地址。

INET_NTOA()将一个IP转换成一个互联网标准点分格式的字符串。

11、不要给“性别”增加索引

简单的说吧,不需要,因为性别,就两个值男与女(人妖不算,呵)。为这两个值建立索引是不值得的,因为无论多少条记录,建立性别的索引,最多让你的语句少检索一半。但与建立索引带来的损失比,捡芝麻丢西瓜。(可能不准确,但大意如些)。

打个比方,数据库就好比一本新华字典,我们查数据时,可以根据拼音来查,字在字典的排序是根据拼音来排序的,我们要查一个字,可以根据拼音很快就能查到我们要查的字,这就叫作聚集索引!换句话说,聚集索引就是按照物理排序的,也因为是按物理排序的,所以一张表只能有一个聚集索引,也是最快的索引。当然,我们也可以根据部首来查,但是这种查询必须先查找到部首,然后再到检索表查到那么字,最后才能查到我们需要的字,你没办法像拼音查法一样翻翻字典就可以查到,这就叫作普通索引。普通索引可以有多个。

假如一本字典里全是"男"和"女"两个字,那么在检索表里也有很多个"男"和"女",这对查询帮助不大。

时间: 2024-10-13 00:27:17

MySQL十大优化技巧详解的相关文章

js十大排序算法详解

十大经典算法导图  图片名词解释:n: 数据规模k:"桶"的个数In-place: 占用常数内存,不占用额外内存Out-place: 占用额外内存 1.冒泡排序 1.1  原始人冒泡排序 function bubbleSort(arr) { var len = arr.length; for (var i = 0; i < len; i++) { for (var j = 0; j < len - 1 - i; j++) { if (arr[j] > arr[j+1]

JAVA8 十大新特性详解

本教程将Java8的新特新逐一列出,并将使用简单的代码示例来指导你如何使用默认接口方法,lambda表达式,方法引用以及多重Annotation,之后你将会学到最新的API上的改进,比如流,函数式接口,Map以及全新的日期API “Java is still not dead—and people are starting to figure that out.” 本教程将用带注释的简单代码来描述新特性,你将看不到大片吓人的文字. 一.接口的默认方法 Java 8允许我们给接口添加一个非抽象的方

Navicat for MySQL 选项设置技巧详解

Navicat for MySQL给用户提供了完整的用户自定义设置界面选项,从主菜单选择工具->选项,但是很多的用户第一次接触,对这方面如何设置不是很了解,本教程将详细的给大家介绍介绍Navicat for MySQL 选项设置技巧详解.希望可以帮到大家. Navicat for MySQL 常规选项 Navicat 常规选项主要包括以下内容: 窗口在工作列显示:每打开一个新窗口时会自动显示在 Windows 任务栏.停用该选项后,当退出 Navicat 主窗口时,所有窗口(例如:表.查询)将会

数据库优化举例详解

数据库优化举例详解 林涛 发表于:2016-3-16 1:01 分类:XSQL/程序/等 标签:mysql,mysql优化 112次 数据库是所有架构中不可缺少的一环,一旦数据库出现性能问题,那对整个系统都会来带灾难性的后果.并且数据库一旦出现问题,由于数据库天生有状态(分主从)带数据(一般还不小),所以出问题之后的恢复时间一般不太可控,所以,对数据库的优化是需要我们花费很多精力去做的. 硬件层优化 这一层最简单,最近几年相信大家对SSD这个名词并不陌生,其超高的IOPS在刚出现在大家视野中的时

训练技巧详解【含有部分代码】Bag of Tricks for Image Classification with Convolutional Neural Networks

训练技巧详解[含有部分代码]Bag of Tricks for Image Classification with Convolutional Neural Networks 置顶 2018-12-11 22:07:40 Snoopy_Dream 阅读数 1332更多 分类专栏: 计算机视觉 pytorch 深度学习tricks 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/e01528

Web攻防系列教程之跨站脚本攻击和防范技巧详解

Web攻防系列教程之跨站脚本攻击和防范技巧详解[XSS] 收藏:http://www.rising.com.cn/newsletter/news/2012-04-25/11387.html 来源:瑞星 2012-04-25 14:33:46 摘要:XSS跨站脚本攻击一直都被认为是客户端Web安全中最主流的攻击方式.因为Web环境的复杂性 以及XSS跨站脚本攻击的多变性,使得该类型攻击很难彻底解决.那么,XSS跨站脚本攻击具体攻击行为是什么,又该如何进行有效的防范呢?本文对此进行了 有针对性的具体

图解MYSQL JOIN ON,SQL JOIN 详解,数据库sql join语句

对于SQL的Join,在学习起来可能是比较乱的.我们知道,SQL的Join语法有很多inner的,有outer的,有left的,有时候,对于Select出来的结果集是什么样子有点不是很清楚.Coding Horror上有一篇文章(实在不清楚为什么Coding Horror也被墙)通过 文氏图 Venn diagrams 解释了SQL的Join.我觉得清楚易懂,转过来. 假设我们有两张表. Table A 是左边的表. Table B 是右边的表. 其各有四条记录,其中有两条记录是相同的,如下所示

深入MySQL用户自定义变量:使用详解及其使用场景案例

一.前言 在前段工作中,曾几次收到超级话题积分漏记的用户反馈.通过源码的阅读分析后,发现问题出在高并发分布式场景下的计数器上.计数器的值会影响用户当前行为所获得积分的大小.比如,当用户在某超级话题下连续第n(n即计数器的值)次进行转发帖子时,将会获得与n相关的分数.然而,在第一次改进后问题依然存在.所以,这次在之前的基础上,通过使用MySQL变量的途径来解决该问题. 二.到底MySQL的变量分哪几类? MySQL变量一共分为两大类:用户自定义变量和系统变量.如下: 用户自定义变量 局部变量 会话

【Android语音合成TTS】百度语音接入方法,和使用技巧详解

请尊重他人的劳动成果,转载请注明出处:[Android语音合成TTS]百度语音接入方法,和使用技巧详解 Ps. 依托于百度开放云,百度语音为合作伙伴提供了业界领先.永久免费的语音技术服务,目前已上线的服务包括语音识别.语义解析.语音合成,后续会继续带来开放资源.多轮对话等技术服务:通过SDK.REST API及离线开发包等多种服务方式,满足不同开发者的开发需求. 目前百度语音提供免费的语音接入,语音合成质量尚可,但还没开放离线TTS. 服务接入流程 具体详情可查看:http://yuyin.ba