设置表名不区分大小写/字符编码/连接数
修改 /etc/my.cnf
vim /etc/my.cnf
添加以下的4行
[mysqld]
lower_case_table_names=1
character_set_server = utf8
max_connections = 1000
max_allowed_packet = 100M
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
设置后保存 重新启动
service mysqld restart
在项目用redis等缓存后,建议关闭数据库缓存
修改 /etc/my.cnf
query_cache_type=1
query_cache_size=64M
query_cache_limit=1M
设置后保存 重新启动
service mysqld restart
是否启用mysql查询缓存,可以通过2个参数:query_cache_type
和query_cache_size
,
其中任何一个参数设置为0都意味着关闭查询缓存功能。
mysql有一个连接超时时间的概念。。。查询此项目的数据库的连接超时时间为28800秒,即为8小时。。
mysql> show global variables like 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout | 28800 |
+---------------+-------+
1 row in set
于是不难得知,肯定是由于项目长时间没有请求数据库,数据库过了8小时和这个连接超时时间之后,就会断开连接。。
而我们的项目使用的是c3p0的连接池,,过了8小时后,连接池中的连接已经被mysql断开了,即连接失效。。
但是c3p0认为此连接却依然有效,此时当我们发请求请求数据库中的数据时,由于连接失效,并不能去连接数据库操纵数据,所以服务器会抛出一个500的错误
问题的原因已经找到,那我们该怎么解决呢??
其实解决起来很简单的。。
先说第一种办法吧,就是将数据库的连接超时时间设置大一点,
msyql> set global wait_timeout=1814400;
msyql> set global interactive_timeout=1814400;
当然这种办法我并不推荐,,这个办法不太好,弊端太多了 比如占用数据库资源,关键是这种办法并不能彻底根治mysql连接断开这种情况
所以我推荐第二种办法:设置c3p0隔多少时间自动检测与数据库的连接,如果断开则自动重连
<bean id="pooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
//下面两个属性就是设置c3p0隔28800秒自动检测与数据库的连接(28800也是mysql的默认的连接超时时间)
<property name="testConnectionOnCheckin" value="true"></property>
<property name="idleConnectionTestPeriod" value="28800"></property>
</bean>
查询Mysql版本
select version();
或者
mysql --version
获取现在的配置
show variables like '%slow%';
show variables like 'long_query_time';
开启
set global long_query_time=5;
set global slow_query_log=1;
关闭
set global slow_query_log=0;
创建文件
cd /var/log/
mkdir mysql
cd mysql
vi mysql-slow.log
设置权限
chmod a+w /var/log/mysql/mysql-slow.log
打开配置文件
vi /etc/my.cnf
找到[mysqld]
下面加上
slow_query_log = 1
slow-query-log-file = /var/log/mysql/mysql-slow.log
long_query_time = 5
long_query_time = 3
中的3表示查询超过3秒才记录;清空日志后慢查询就不会继续写入了,重启后才能继续写入
set global slow_query_log=0;
set global slow_query_log=1;
常见的连接参数
jdbc:mysql://localhost:3306/test?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&rewriteBatchedStatements=true
characterEncoding=utf8
字符编码utf8zeroDateTimeBehavior=convertToNull
时间传入了0000-00-00 自动转换为nullrewriteBatchedStatements=true
高性能的批量插入或更新(保证5.1.13以上版本的驱动)将vm.swappiness设置为0-10
具体这样做:
1) 查看你的系统里面的swappiness
cat /proc/sys/vm/swappiness
不出意外的话,你应该看到是0
2) 修改swappiness值为10
sudo sysctl vm.swappiness=10
但是这只是临时性的修改,在你重启系统后会恢复默认的值,所以,还要做一步:
vi /etc/sysctl.conf
在这个文档的最后加上这样一行:
vm.swappiness = 10
然后保存,这样重启之后配置也不会失效。
将vm.dirty_background_ratio设置为5-10,将vm.dirty_ratio设置为它的两倍左右,以确保能持续将脏数据刷新到磁盘,避免瞬间I/O写,产生严重等待
cat /proc/sys/vm/dirty_background_ratio
cat /proc/sys/vm/dirty_ratio
sudo sysctl vm.dirty_background_ratio=10
sudo sysctl vm.dirty_ratio=20
此优化主要针对innodb引擎
创建慢查询日志文件
cd /var/log/
mkdir mysql
cd mysql
vi mysql-slow.log
打开配置文件
vi /etc/my.cnf
找到[mysqld]
下面加上
[mysqld]
lower_case_table_names=1
character_set_server = utf8
max_allowed_packet = 100M
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
# 强烈推荐采用innodb引擎,
default-storage-engine = InnoDB
# 连接排队列表总数
# back_log值指出在MySQL暂时停止回答新请求之前的短时间内多少个请求可以被存在堆栈中。也就是说,如果MySql的连接数达到max_connections时,新来的请求将会被存在堆栈中,以等待某一连接释放资源,该堆栈的数量即back_log,如果等待连接的数量超过back_log,将不被授予连接资源
back_log = 200
max_connections = 1000
# 查询结果缓存
# 建议关闭query cache功能或降低设置不要超过512M
# 如果项目用了redis等缓存,建议把数据库缓存关闭
query_cache_type=0
query_cache_size=64M
query_cache_limit=1M
# 取消文件系统的外部锁
skip-external-locking
# 默认,innodb_flush_log_at_trx_commit=1,表示在每次事务提交的时候,都把log buffer刷到文件系统中去,并且调用文件系统的“flush”操作将缓存刷新到磁盘上去。这样的话,数据库对IO的要求就非常高了,如果底层的硬件提供的IOPS比较差,那么MySQL数据库的并发很快就会由于硬件IO的问题而无法提升。
# innodb_flush_log_at_trx_commit=0时,每隔一秒把log buffer刷到文件系统中去,并且调用文件系统的“flush”操作将缓存刷新到磁盘上去。这样的话,可能丢失1秒的事务数据。
# innodb_flush_log_at_trx_commit=2时,在每次事务提交的时候会把log buffer刷到文件系统中去,但是每隔一秒调用文件系统的“flush”操作将缓存刷新到磁盘上去。如果只是MySQL数据库挂掉了,由于文件系统没有问题,那么对应的事务数据并没有丢失。只有在数据库所在的主机操作系统损坏或者突然掉电的情况下,数据库的事务数据可能丢失1秒之类的事务数据。这样的好处就是,减少了事务数据丢失的概率,而对底层硬件的IO要求也没有那么高(log buffer写到文件系统中,一般只是从log buffer的内存转移的文件系统的内存缓存中,对底层IO没有压力)。MySQL 5.6.6以后,这个“1秒”的刷新还可以用innodb_flush_log_at_timeout 来控制刷新间隔。
innodb_flush_log_at_trx_commit=2
# 索引缓存,根据内存大小而定,如果是独立的db服务器,可以设置高达80%的内存总量
# 指定用于索引的缓冲区大小,增加它可得到更好的索引处理性能。对于内存在4GB左右的服务器来说,该参数可设置为256MB或384MB。
key_buffer_size = 512M
# 打开表缓存总数,可以避免频繁的打开数据表产生的开销
# 给经常访问的表分配的内存,物理内存越大,设置就越大。调大这个值,一般情况下可以降低磁盘IO,但相应的会占用更多的内存,这里设置为614。
table_open_cache = 614
# 每个线程排序所需的缓冲
sort_buffer_size = 4M
# 每个线程读取索引所需的缓冲
read_buffer_size = 4M
# 缓存可重用的线程数
thread_cache_size = 128
# 记录慢查询,然后对慢查询一一优化
slow_query_log = 1
slow-query-log-file = /var/log/mysql/mysql-slow.log
long_query_time = 5
# 调整innodb_buffer_pool_size大小,考虑设置为物理内存的50%-60%左右。
# InnoDB使用一个缓冲池来保存索引和原始数据,设置越大,在存取表里面数据时所需要的磁盘I/O越少。
# 强烈建议不要武断地将InnoDB的Buffer Pool值配置为物理内存的50%~80%,应根据具体环境而定。
innodb_buffer_pool_size = 3096M
# 设置innodb_file_per_table = 1,使用独立表空间
innodb_file_per_table = 1
# 设置innodb_log_file_size=256M,设置innodb_log_files_in_group=2,基本可满足90%以上的场景;
# 不要将innodb_log_file_size参数设置太大,这样可以更快同时又更多的磁盘空间,丢掉多的日志通常是好的,在数据库崩溃后可以降低恢复数据库的事件
innodb_log_file_size=256M
innodb_log_files_in_group=2
# 设置内存临时表最大值。如果超过该值,则会将临时表写入磁盘,其范围1KB到4GB。
tmp_table_size = 64M
# 独立的内存表所允许的最大容量。
max_heap_table_size = 64M
like '%haha%'
一般不要用MySQL数据库
比如这个语句在这个数据库查询很慢:
select a from tms where b like ‘%haha%’ order by time limit 100; 第一种优化方法(注意:这种方法只适用于haha开头的):
将haha字段和time字段加索引(联合索引还是普通索引自己看情况)
select a from news where b like ‘haha%’ order by time limit 100; 第二种优化方法(注意:这种方法只适用于mysql引擎是myisam的):
语句不变,将haha字段加为全文索引,time字段变为普通索引
select a from news where b like ‘%haha%’ order by time limit 100; 第三种方法:
这是因为我必须用 %haha%
这种方式,而且还不能更换数据库引擎的情况下。
我是把like的操作放到了java程序中来处理,一次取定量数据进行筛选,如果没取够,再取,再筛选……这样就避免了完全扫表了,只扫部分数据。成功解决。
如果sql语句返回只可能只有一条,一定要添加LIMIT 1,来避免全部检索。
参见:Mysql优化-索引
是什么
mysql提供可以用来分析当前会话中语句执行的资源消耗情况。 可以用于SQL的调优的测量,相比explain,show profile展示的数据更加详尽。
怎么用
-- 查看是否开启
show variables like 'profiling';
-- 开启功能,默认是关闭,使用前需要开启
set profiling=1;
-- 查看结果
show profiles;
-- 诊断SQL
show profile cpu,block io for query <query_id>;
-- 还可以下面这句通过获取
SELECT * FROM information_schema.profiling WHERE query_id = <query_id> ORDER BY seq;
The total number of locks exceeds the lock table size错误
show variables like "innodb_buffer_pool_size";
默认为8M
修改 innodb_buffer_pool_size的值为3G:
3*1024*1024*1024
,不要忘记;号
SET GLOBAL innodb_buffer_pool_size=67108864;