根据这篇文章,看起来我在 MySQL 优化方面遇到了一些严重的问题。
不幸的是,我不知道从哪里开始!
我正在运行基于 DirectAdmin 的 CentOS 专用服务器。它是具有 8Gb RAM 的英特尔四核 3Ghz。我在上面运行了许多网站,但我相信只有我的主网站才能获得真正的流量。
我担心的网站每周有大约 30,000 名独立访问者/250,000 次点击。这是一个基于 WordPress 的网站。
我my.cnf的基本上是空的。我增加了max_connections处理初始问题的能力(根据之前链接的帖子,网站不断出现“数据库最大连接数”错误),仅此而已。
我尝试在服务器上运行两个脚本来确定如何优化我的设置。其中一个不起作用,但另一个建议如下:
query_cache_sizetable_cachetable_definition_cache价值。I have a legacy IBM DB2 database table that contains lots of records of phone calls. It has columns for ID, customer number, employee who took the call, etc. The date/time for each call is kept in a pair of columns, ROSDAT and ROSTIM. ROSDAT is an 8 byte numeric column, and ROSTIM is a 6 byte numeric. Example:
ROSDAT ROSTIM
20111006 163243
20111007 012335
Run Code Online (Sandbox Code Playgroud)
So for the first row the date is 2011-10-06, and the time is 16:32:43. There …
我有一些表可以从Postgres SQL 中的CLUSTER ON/CLUSTER USING中受益匪浅:
# CLUSTER table USING index_name;
# ANALYZE VERBOSE table;
# CLUSTER VERBOSE;
Run Code Online (Sandbox Code Playgroud)
维护任务会定期运行 CLUSTER VERBOSE 以保持最新状态。但是,在运行 CLUSTER VERBOSE 之前,是否可以运行测试来查看表的碎片化程度?也许是这样的:
# CLUSTER ANALYZE
table 40000 records. 4000 observed clusters, 5000 potential clusters (20% fragmentation)
Run Code Online (Sandbox Code Playgroud)
请注意,我使用 CLUSTER,因此同时访问的数据被“整理”为少量磁盘块。例如,每个页面都有数千个属性。aCLUSTER page_attribute USING page_id;将所有属性放在一起,大大减少了磁盘负载。
在my.cnf我有:
table_cache = 524288
open_files_limit = 65535
Run Code Online (Sandbox Code Playgroud)
两者都处于 mysql 配置的最大允许值。两者都小于最大打开文件限制:
# cat /proc/sys/fs/file-max
2097152
Run Code Online (Sandbox Code Playgroud)
MySQL 变量状态:
mysql> SHOW GLOBAL STATUS LIKE 'open%';
+--------------------------+--------+
| Variable_name | Value |
+--------------------------+--------+
| Open_files | 193 |
| Open_streams | 0 |
| Open_table_definitions | 594 |
| Open_tables | 802 |
| Opened_files | 537248 |
| Opened_table_definitions | 4895 |
| Opened_tables | 9174 |
+--------------------------+--------+
7 rows in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
服务器有 32GB 内存。大部分免费!
尽管如此,当我运行 mysqltuner 脚本时:
它说: …
负责监视和调整 SQL Servers 2012 Enterprise Ed。Windows Server 2008 R2 Standard Ed 上的 SP1(64 位)。
所有这些都在虚拟机中运行。单个 RAID10 或 RAID5 上的每个区域办事处一个 SQL Server。换句话说,我无法使用不同的物理单元(硬盘驱动器)配置 SQL Server。
我观察到tempdb系统数据库上的读取和写入延迟升高。
在减少tempdb数据库延迟方面,我有哪些选择?
sql-server optimization database-tuning configuration tempdb
我在表上有一个articles列的全文索引content,title并且keywords
在对每一列进行搜索时,像这样select count(1) from articles where match(content,title,keywords) against ('cats' in boolean mode),结果需要 12 到 15 秒。
但是单独处理这些列 ( select count(1) from articles where match(content) against ('cats' in boolean mode)) 通常需要不到 50 毫秒。
为什么搜索 3 列的时间比单独搜索所有列的时间长 100 多倍?
这不是如何让它更快的问题,而是更多地问“为什么这么慢?”
表/索引
id int(30) PK auto_increment
url varchar(1024)
title varchar(255) FULLTEXT
content text FULLTEXT
keywords varchar(1024) FULLTEXT
comments text
created_date int(11)
posted_date int(11)
Run Code Online (Sandbox Code Playgroud)
说明
第一个是多列查询:

第二个是新的更快的查询,它分别运行 3 列然后合并它们(查询缓存已清除)。

全文列顺序

使用/强制索引与解释

我在 SQL Server 2012 中有一堆表。
这些表由其他表提供。每天都有一些例程会截断(完全删除)它们并运行将结果插入其中的查询。它们就像静态视图,存储那些处理过的数据,以便更快地查询它们。
还有源表,每天接收数百万条新记录,这些不会被删除。
所有这些表都有一段时间会插入很多内容,而在一天的剩余时间里,它们只会被读取。
即使使用这些“静态视图”表,我认为我也可以提高整体性能。是否有处理这些行为的最佳实践?
对于第一种情况,我运行了一些基准测试,发现最好的性能来自对过滤最多的字段使用非聚集索引。我在截断之前删除这些索引并在插入后重新创建它们。删除和重新创建比重建更快,插入也更快。
我也应该保留 PK(没有语义意义)和聚集索引吗?我想如果没有索引,这些插入会更快,但是如果这些表没有 PK,我会有什么问题吗?它们从不明确使用。
我问这个是因为当我创建表并设置它的 PK 时
idBenchmark int NOT NULL IDENTITY (1,1) PRIMARY KEY
Run Code Online (Sandbox Code Playgroud)
聚集索引是自动创建的,具有随机名称,因此我无法删除并重新创建它。
sql-server optimization clustered-index nonclustered-index query-performance
我在生产中有一个pageviews包含 4M 行的 MySQL 表,用于记录用户在帖子上的页面浏览量。我需要知道特定用户阅读了哪些帖子,但此请求最多需要 15 秒才能执行:
SELECT post_id
FROM pageviews
WHERE user_id = 981
GROUP BY post_id
Run Code Online (Sandbox Code Playgroud)
下面是执行计划:
mysql> EXPLAIN SELECT post_id FROM visits WHERE user_id = 981 GROUP BY post_id;
+----+-------------+--------+------+---------------+---------+---------+-------+-------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+------+---------------+---------+---------+-------+-------+----------------------------------------------+
| 1 | SIMPLE | visits | ref | user_id | user_id | 5 | const | 54696 | Using where; Using temporary; …Run Code Online (Sandbox Code Playgroud) 我想测试 tempdb 溢出警告,所以我在 SQL Server 2014 上运行以下脚本:
USE tempdb
IF OBJECT_ID('tempdb..tblTest') IS NOT NULL DROP TABLE tblTest
CREATE TABLE tblTest
(
c1 INT PRIMARY KEY CLUSTERED,
c2 INT ,
c3 CHAR (1000)
);
GO
SET NOCOUNT ON;
BEGIN TRANSACTION;
DECLARE @i AS INT;
SET @i = 1;
WHILE @i <= 10000
BEGIN
INSERT INTO tblTest (c1, c2, c3)
VALUES (@i, @i, 'a');
SET @i = @i + 1;
END
COMMIT TRANSACTION;
GO
UPDATE STATISTICS dbo.tblTest
GO
SET STATISTICS XML ON; …Run Code Online (Sandbox Code Playgroud) sql-server optimization sorting sql-server-2014 query-performance
我在 ExtJS 中开发了 SQL Server 2012 中查询结果的报告。
我将 Ext.Grid 与分页一起使用,因此我可以使用偏移量来限制查询将返回的记录数量。但是为了让这个 ExtJS 功能起作用,我仍然必须向它提供给定查询所具有的记录总数。
有些报告在白天使用过滤器和数据更改,因此我只能通过运行查询来知道总数。这导致运行它两次:一次使用 count(*) 获得总计数,再次获得正确的数据。
有没有办法找到查询的总数,即使它有偏移命令,而不必像我现在所做的那样运行它两次,也不必循环遍历所有记录?
optimization ×10
mysql ×4
performance ×4
sql-server ×4
cache ×1
db2 ×1
my.cnf ×1
postgresql ×1
sorting ×1
storage ×1
tempdb ×1