how to optimize mysql for high traffic drupal site

本文探讨了如何通过调整MySQL配置来优化Drupal站点性能,包括改变表引擎为InnoDB以减少锁定问题,发现并优化慢查询,合理设置my.cnf参数如连接数限制、等待超时等,以及调整查询缓存大小等措施。适用于处理高流量和数据库密集型网站。

Configuring Mysql could be a daunting task if your Drupal site begins to scale and you start getting "too many connections" error or mysql server down errors. We had this opportunity to scale a Drupal site to 2 million page views a month and we improved this with success. So, lets start and share what we found out. I would be glad to hear from other people's experiences as well in the comment section.

 

Drupal 6 comes with MyISAM engine default. First thing you would notice with your drupal site would be your tables locking. Site would begin to go down and when you look at the mysql processes (using mysql tools or command line), I know this would feel like cursing Drupal or Mysql, but before you begin to hit at Drupal and feeling bad about Drupal performance, please try and change your Drupal tables to InnoDB

 

You would not be able to change all the tables like node revision if similar module is used. Node revision is dependent on MySQL's FULLTEXT indexing for MyISAM tables if similar module is enabled. FULLTEXT does not work with InnoDB.

 

    ALTER  TABLE  `node`   ENGINE  = InnoDB

Locking would go away. MYISAM locks table whenever an update/insert/delete operation is happening on a node table for example. This keeps other operations on wait. When we have too many such operations in queue, this locking builds up and brings the site to halt. InnoDB does locking at the record level, thus preventing the above case.

 

Discover Mysql Slow Queries:

 

This should be the next step to improve mysql performance. Find out the sql queries that are slow or repeating. This is done as follows:

 

a. Use Devel module. This would list the sql queries that are being executed when a page loads. Monitor the unusal slow sql query or queries repeating. Ask yourself: Is there an sql query that can be optimized or can be removed?

 

b. Log Mysql slow queries as follows in /etc/my.cnf

 
log-slow-queries=/var/lib/mysqllogs/slow-log
long_query_time=2
log-queries-not-using-indexes

 

Configuring my.cnf:

Here comes the complex part. This may be tricky. 

 

Here is my my.cnf:

 

a.  Limit mysql connections. This is important to set. If it is too high, your server would stop responding and you would have to reboot.  If it too less, you would start getting "too many connections" error on your Drupal site.  I keep it high enough that I never get too many connections error.

 

max_connections=100

 

 

b. If you see too many sleep connections in your mysql processes (SHOW PROCESSLIST), this means that the there is no mysql operation but the mysql connection is still retained. This prevents the mysql connection to be released and taken up by some other process. You would need to reduce the wait_timeout.

wait_timeout=600

 

c. If you changed to InnoDB, make the following changes to my.cnf:

[mysqld]
 # InnoDB settings
 innodb_data_home_dir = /var/lib/mysql/
 innodb_data_file_path = ibdata1:100M:autoextend
 set-variable = innodb_buffer_pool_size=100M
 set-variable = innodb_additional_mem_pool_size=10M
 innodb_flush_log_at_trx_commit=1 

 

The innodb_data_home_dir setting defines the location where InnoDB should create data files. The innodb_data_file_path setting defines the name of the data files. In this case, it will create a 100MB data file called ibdata1 and will extend the size as needed. A data file in InnoDB parlance is a tablespace.

 

d.Logging slow sql queries:

 

log-slow-queries=/var/lib/mysqllogs/slow-log
long_query_time=2
log-queries-not-using-indexes
 

e. Max allowed packet to be increased from 32M to 128M. Typically, if you are not storing your cache in memcache and in mysql tables, you would need to increase this size.

 

 

max_allowed_packet=128M

 

f. Query Cache size to be adjusted:

query_cache_size=4M
query_cache_limit = 2M
sort_buffer_size=2M
read_buffer_size=2M
read_rnd_buffer_size=4M

 

For a high traffic site which is database intensive and has a dedicated 16GB server to mysql, my my.cnf looks like:

 

[mysqld]
datadir=/var/lib/mysql
tmpdir=/var/lib/mysqltmp
socket=/var/lib/mysql/mysql.sock
skip-locking
skip-name-resolve
table_cache=2048
thread_cache_size=32
back_log=100
max_connect_errors=10000
open-files=10000
interactive_timeout=400
wait_timeout=300
max_connections=500
skip-bdb
log-slow-queries=/var/lib/mysqllogs/slow-log
long_query_time=2
log-queries-not-using-indexes
max_allowed_packet=128M
tmp_table_size=256M
max_heap_table_size=256M
query_cache_size=32M
query_cache_limit = 6M
sort_buffer_size=4M
read_buffer_size=4M
read_rnd_buffer_size=16M
join_buffer_size=2M
default-storage-engine=InnoDB
key_buffer_size=128M
myisam_sort_buffer_size=64M
innodb_log_file_size=100M
innodb_buffer_pool_size=6G
innodb_additional_mem_pool_size=20M
innodb_support_xa = 0
[mysql.server]
user=mysql
[mysqld_safe]
### 回答1: To perform a MySQL ngram join tables fulltext search, you can follow these steps: 1. Enable ngram fulltext search in your MySQL server: You can enable ngram fulltext search by adding the following line to your MySQL configuration file (e.g., `/etc/my.cnf` or `/etc/mysql/my.cnf`): ``` [mysqld] innodb_ft_server_stopword_table= '' innodb_ft_enable_stopword=0 innodb_ft_min_token_size=2 innodb_ft_enable_keys=1 innodb_ft_ngram_token_size=3 ``` The above configuration enables ngram tokenization and indexing for fulltext searches in your MySQL server. 2. Create and populate the tables: Create the tables you want to join and add a fulltext index to each table using the ngram tokenization technique. For example, if you have two tables, `table1` and `table2`, you can create and populate them as follows: ``` CREATE TABLE table1 ( id INT(11) NOT NULL AUTO_INCREMENT, text TEXT, FULLTEXT INDEX (text) ) ENGINE=InnoDB; CREATE TABLE table2 ( id INT(11) NOT NULL AUTO_INCREMENT, text TEXT, FULLTEXT INDEX (text) ) ENGINE=InnoDB; INSERT INTO table1 (text) VALUES ('The quick brown fox'); INSERT INTO table1 (text) VALUES ('jumps over the lazy dog'); INSERT INTO table2 (text) VALUES ('The quick brown fox'); INSERT INTO table2 (text) VALUES ('jumps over the lazy dog'); ``` 3. Join the tables: To perform a fulltext search using the ngram technique, you can join the tables on their fulltext index columns. For example, if you want to find all the records that contain the word "brown" in both `table1` and `table2`, you can use the following query: ``` SELECT table1.*, table2.* FROM table1 JOIN table2 ON MATCH(table1.text) AGAINST('brown' IN NATURAL LANGUAGE MODE) AND MATCH(table2.text) AGAINST('brown' IN NATURAL LANGUAGE MODE) ``` This query joins `table1` and `table2` on their fulltext index columns and performs a fulltext search for the word "brown" using the ngram technique. Note: Keep in mind that ngram fulltext search can be resource-intensive, especially if you have a large amount of data. You may need to optimize your MySQL server or adjust the ngram tokenization parameters to improve performance. ### 回答2: 要实现MySQL的Ngram连接表全文搜索,你可以按照以下步骤操作: 1. 确保你的MySQL版本支持Ngram全文索引。Ngram索引是一种特殊的全文索引,可以在词组级别上进行索引和匹配。从MySQL 5.7版本开始,Ngram索引被引入并成为MySQL的一部分。 2. 在需要进行全文搜索的表中添加Ngram索引。你需要将需要搜索的文本字段定义为Ngram类型,并为该字段创建Ngram索引。例如,假设你的表名为"table_name",字段名为"textfield_name",你可以使用以下命令创建Ngram索引: ALTER TABLE table_name ADD FULLTEXT INDEX idx_ngram_textfield_name (textfield_name) WITH PARSER NGRAM; 3. 要进行Ngram连接表全文搜索,你需要使用JOIN语句将两个表连接起来,并使用MATCH AGAINST条件进行全文搜索。例如,假设你有两个表名为"table1"和"table2",它们之间通过字段"field1"和"field2"进行连接,你可以使用以下语句进行全文搜索: SELECT table1.* FROM table1 INNER JOIN table2 ON MATCH (table1.field1) AGAINST (table2.field2 IN NATURAL LANGUAGE MODE); 注意,这里的关键是使用MATCH AGAINST条件进行全文搜索,并设置适当的匹配模式。你可以根据需要选择不同的匹配模式,如BOOLEAN模式、NATURAL LANGUAGE MODE等。 4. 执行以上查询语句后,MySQL将根据Ngram索引的内容从两个表中进行匹配,并返回与搜索条件匹配的结果。 需要注意的是,Ngram全文搜索可能在大型数据集上性能不佳,因为它需要对每个词组进行索引和匹配。在使用Ngram全文搜索时,你应该考虑数据库性能,并根据实际情况进行性能优化和调整。 ### 回答3: 要实现MySQL ngram联接表的全文搜索,需要按照以下步骤进行: 1. 安装MySQL插件:首先,需要安装MySQL插件,以支持ngram搜索功能。在安装过程中,需要注意将插件正确地配置和加载到MySQL中。 2. 创建表:根据需要创建要进行联接的表。确保每个表都具有适当的字段定义,并使用适当的字段类型,例如varchar或text。 3. 添加索引:为了实现快速全文搜索,需要在每个表的相关字段上添加适当的全文搜索索引。对于ngram搜索,可以使用FULLTEXT索引类型。 4. 创建联接查询:编写SQL查询语句,以使用ngram联接表和全文搜索功能。联接查询应该使用JOIN操作符来连接相关表,并在WHERE子句中使用MATCH AGAINST语句来进行全文搜索。 5. 配置ngram参数:通过设置MySQL的ngram参数,可以调整ngram搜索的行为。例如,可以设置ngram的最小和最大字词长度,以及最小的重要性阈值。 6. 测试查询:运行查询语句并测试数据库的响应时间和返回结果的准确性。根据需要,对查询进行调整和优化,以获得更好的性能和结果。 总结起来,要实现MySQL ngram联接表的全文搜索,需要安装插件、创建表、添加索引、编写联接查询、配置ngram参数,并进行测试和优化。这些步骤将帮助您有效地实现所需的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值