27-06-2018 0 条评论

我们在使用MYSQL的时候,并不是你建立了索引,你执行的SQL语句就一定会走索引,反之当数据量大的时候,走全表扫描,就会出现慢查询,为此我们有方法可以规避这种问题。
首先在这里不得不提下explain,关于它的用法,这里有详细的介绍 EXPLAIN的用法

索引列参与计算

如果where条件中age列中使用了计算,则不会使用该索引

SELECT `*` FROM `user` WHERE `age`=20; // 会使用索引
SELECT `*` FROM `user` WHERE `age`+10=30;// 不会使用索引!!因为所有索引列参与了计算
SELECT `*` FROM `user` WHERE `age`=30-10;//会使用索引

所以需要计算的话,不要放在索引列中,想办法放到右边去。

索引列使用了函数

同样的道理,索引列使用了函数,一样会导致相同的后果

SELECT `*` FROM `user` WHERE concat(`name`,'abc') ='bewynabc'; //不会使用索引,因为使用了函数运算,原理与上面相同
SELECT `*` FROM `user` WHERE `name` =concat('bewyn','abc');  // 会使用索引

索引列使用了Like %XXX

SELECT * FROM `user` WHERE `name` LIKE 'bewyn%'  //走索引
SELECT * FROM `user` WHERE `name` LIKE '%bewyn'  // 不走索引

所以当需要搜索email列中.com结尾的字符串而email上希望走索引时候,可以考虑数据库存储一个反向的内容reverse_email

SELECT * FROM `table` WHERE `reverse_email` LIKE REVERSE('%.com');  // 走索引

注:以上如果你使用REVERSE(email) = REVERSE(‘%.com’),一样得不到你想要的结果,因为你在索引列email列上使用了函数,MySQL不会使用该列索引

同样的,索引列上使用正则表达式也不会走索引。

字符串列与数字直接比较

这是一个坑,假设有一张表,里面的a列是一个字符char类型,且a上建立了索引,你用它与数字类型做比较判断的话:

 SELECT * FROM `user` WHERE `a`='1' //走索引
 SELECT * FROM `user` WHERE `a`=1   //字符串和数字比较,不走索引!

但是如果那个表那个列是一个数字类型,拿来和字符类型的做比较,则不会影响到使用索引

 SELECT * FROM `user` WHERE `b`='1'   //虽然b是数字类型,和'1'比较依然走索引

但是,无论如何,这种额外的隐式类型转换都是开销,而且由于有字符和数字比就不走索引的情况,故建议避免一切隐式类型转换

尽量避免 OR 操作

select * from user where name='bewyn' or address='sh' or phone=137xxx //这样的语句,即使条件中有带索引的列也不会走索引,除非全部建立索引。

所以除非每个列都建立了索引,否则不建议使用OR,在多列OR中,可以考虑用UNION 替换

select * from user where name='bewyn' union
select * from user where address='sh' union
select * from user where phone=137xxx
10-02-2017 0 条评论

在开发中,常遇到mysql查询一对多时,会显示成多条记录组成,这样在PHP环境中,去读取数据的时候,就会很麻烦,不能按照循环记录去读取。
使用下面方法可以解决这个问题,就可以使用循环去读取数据,其它的多条记录,显示在字段中,并且默认以逗号隔开。

数据表结构

A 表

id pid text

1 2 123
2 3 456

B 表

id aid con

1 2 111
2 2 222

SELECT a.id,a.text,group_concat(b.con) as con FROM a RIGHT JOIN b ON a.id=b.aid WHERE a.id=2 GROUP BY b.aid;
mysql> SELECT a.id,a.text,group_concat(b.con) as con FROM a RIGHT JOIN b ON a.id=b.aid WHERE a.id=2 GROUP BY b.aid;
+----+------+---------+
| id | text | con |
+----+------+---------+
| 2 | 456 | 111,222 |
+----+------+---------+
1 row in set

这样我们就可以PHP中实现循环,并且其它的多条记录字段都是显示在循环中的一条记录中。

02-08-2016 0 条评论

因为发现很多人不会源码安装lnmp环境,刚好准备搭建环境,所以把基本步骤写出来,以后大家照着敲就可以。
本次搭建使用的都是最新的nginx1.11.3和php7(号称比5.6有2倍的性能提升),以及mysql5.7.13(号称有着一倍的性能提升)。
首先我们来安装mysql5.7.13
因为使用的是ubuntu12.04所以使用deb安装,见地址,先下载下来。

wget http://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-server_5.7.14-1ubuntu12.04_amd64.deb-bundle.tar

然后解压:

tar xvf mysql-server_5.7.14-1ubuntu12.04_amd64.deb-bundle.tar

会得到如下文件:

 1.mysql-common_5.7.14-1ubuntu14.04_amd64.deb
2.libmysqlclient20_5.7.14-1ubuntu14.04_amd64.deb
3.libmysqlclient-dev_5.7.14-1ubuntu14.04_amd64.deb
4.libmysqld-dev_5.7.14-1ubuntu14.04_amd64.deb
5.mysql-community-client_5.7.14-1ubuntu14.04_amd64.deb
6.mysql-client_5.7.14-1ubuntu14.04_amd64.deb
7.mysql-community-server_5.7.14-1ubuntu14.04_amd64.deb

依次安装执行:

sudo dpkg -i mysql-common_5.7.14-1ubuntu12.04_amd64.deb libmysqlclient20_5.7.14-1ubuntu12.04_amd64.deb libmysqlclient-dev_5.7.14-1ubuntu12.04_amd64.deb libmysqld-dev_5.7.14-1ubuntu12.04_amd64.deb mysql-client_5.7.14-1ubuntu12.04_amd64.deb mysql-community-server_5.7.14-1ubuntu12.04_amd64.deb

其间会提输入root密码。
添加mysql用户组和用户。
groupadd mysql
useradd -r -g mysql mysql
默认安装的文件在:
配置文件:/etc/mysql/my.cnf
datadir:/var/lib/mysql 需要赋予mysql权限 chown -R mysql:mysql ./
mysqld /usr/sbin/mysqld
如果安装完成之后没有看到data文件夹,可以操作下面的步骤。
/usr/sbin/mysqld –user=mysql –datadir=/var/lib/mysql/data/mysql –initial –initialize-insecure
现在可以启动mysql服务了。
/etc/init.d/mysql start
nginx安装
wget https://nginx.org/download/nginx-1.11.3.tar.gz
tar zxvf nginx-1.11.3.tar.gz
cd nginx-1.11.3
groupadd nginx
useradd -r -g nginx nginx

./configure --prefix=/usr/local/nginx \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--user=nginx \
--group=nginx \
--with-http_gzip_static_module \
--with-pcre \

通常安装nginx需要使用zip和pcre一个是用来数据传输压缩及使用正则表达式(rwrite)
make && make install
PHP安装
wget http://cn2.php.net/distributions/php-7.0.9.tar.gz
tar zxvf php-7.0.9.tar.gz
cd php-7.0.9

./configure --prefix=/usr/local/php7 \
--with-config-file-path=/usr/local/php7/etc \
--with-mcrypt=/usr/include \
--with-gd \
--with-iconv \
--with-zlib \
--enable-xml \
--enable-bcmath \
--enable-shmop \
--enable-sysvsem \
--enable-inline-optimization \
--enable-mbregex \
--enable-fpm \
--enable-mbstring \
--enable-ftp \
--enable-gd-native-ttf \
--with-openssl \
--enable-pcntl \
--enable-sockets \
--with-xmlrpc \
--enable-zip \
--enable-soap \
--without-pear \
--with-gettext \
--enable-session \
--with-curl \
--with-jpeg-dir \
--with-freetype-dir \
--enable-sockets \
--enable-opcache \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd

因为php7版本不支持mysql,所以这里不需要安装。
当然对于一个新的ubuntu系统,不能顺利的完成检测。
所以这时候就要根据系统的提示安装相应的软件,如:libxml2、jpg、png、curl等。
可以使用ubuntu系统自带的apt-get install。
make && make install
nginx与php-fpm通讯
一般安装完成php就有php-fpm,不过相应的配置文件可能要重新命名。
即php7/etc/php-fpm.conf.default
cp php-fpm.conf.default php-fpm.conf
因为fpm.conf默认使用的是nobody用户名及用户组,系统中是不存在的,所以需要新建。
groupadd nobody
useradd -r -g nobody nobody
现在切换到nginx,使它能与php-fpm通讯。
打开下面的注释。

 location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}

至此,lnmp环境就已经装好了,现在你的程序开始启航了。