我有一个几乎从不查询的数据包日志数据库。它只需要快速插入即可。我使用 InnoDB 是因为我想保持 ACID 合规性,因为即使丢失一个数据包也可能对我们的客户造成损害。在性能调优方案中,我通过多个数据库连接向服务器发送 1,000,000 个数据包。但是无论我在 my.cnf 中使用什么设置,我都无法让 mysqld 进程在 12 核的系统上使用超过 900% 的 CPU。(盒子上没有其他东西在运行。)
我设置了以下内容
innodb_file_per_table = 1innodb_write_io_threads = 64innodb_read_io_threads = 64innodb_thread_concurrency = 0如果我使用 MyISAM,我可以在大约 6 秒内写入所有数据包。但是 InnoDB 大约需要 25。我可以让 MySQL 使用剩余的系统资源并更快地插入吗?
编辑:这是表的架构:
+-------+----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------------------+------+-----+---------+-------+
| t | bigint(20) unsigned | YES | | NULL | |
| a | char(1) | YES | | NULL | |
| sa | …Run Code Online (Sandbox Code Playgroud) 我的应用程序依赖于为某些表运行“显示列”。运行大约需要 60 毫秒,而我们所有其他查询都需要不到 1 毫秒。information_schema直接查询甚至更慢。
该数据库包含约250个数据库,每个数据库有100到200张表(总共约2万张表)。
(该应用程序每页加载执行大约 14 个这样的查询 - 我很清楚需要清理这个遗留代码,但在我进行长期修复时寻找可能的选项。)
我有几个表,每个表有 100-300 列整数类型,它们保存高度易变的数据。数据集由一两个主键作为键,刷新时删除整个数据集,并在一个事务中插入新数据。数据集大小通常是几百行,但在极端情况下可以达到几千行。每秒刷新一次,不同键的数据集更新通常是脱节的,因此删除和重新创建表是不可行的。
我如何调整 Postgres 来处理这样的负载?如果这有什么不同,我可以使用最新和最好的版本。
我有一张表,其中包含家庭的详细信息,而另一个表则包含与这些家庭相关的所有人员的详细信息。对于家庭表,我使用其中的两列定义了一个主键 - [tempId,n]。对于 person 表,我有一个使用其 3 列定义的主键[tempId,n,sporder]
使用主键上的聚集索引所指示的排序,我为每个家庭[HHID]和每个人的[PERID]记录生成了一个唯一 ID (下面的代码片段用于生成 PERID]:
ALTER TABLE dbo.persons
ADD PERID INT IDENTITY
CONSTRAINT [UQ dbo.persons HHID] UNIQUE;
Run Code Online (Sandbox Code Playgroud)
现在,我的下一步是将每个人与相应的家庭相关联,即;将 a 映射[PERID]到 a [HHID]。两个表之间的人行横道基于两列[tempId,n]。为此,我有以下内部连接语句。
UPDATE t1
SET t1.HHID = t2.HHID
FROM dbo.persons AS t1
INNER JOIN dbo.households AS t2
ON t1.tempId = t2.tempId AND t1.n = t2.n;
Run Code Online (Sandbox Code Playgroud)
我总共有1928783个户籍记录和5239842个人记录。执行时间目前非常高。
现在,我的问题:
我已将SQL Server 2008 为整个脚本生成的执行计划上传到 SQLPerformance.com
我有一个 INNODB 表levels:
+--------------------+--------------+------+-----+ -------+-------+ | 领域 | 类型 | 空 | 钥匙 | 默认 | 额外 | +--------------------+--------------+------+-----+ -------+-------+ | 身份证 | 整数(9) | 否 | PRI | 空 | | | 级别名称 | varchar(20) | 否 | | 空 | | | 用户 ID | 整数(10) | 否 | | 空 | | | 用户名 | varchar(45) | 否 | | 空 | | | 评级 | 十进制(5,4) | 否 | | 0.0000 | | | …
mysql innodb performance optimization index-tuning query-performance
此查询在 ~21 秒内运行(执行计划):
select
a.month
, count(*)
from SubqueryTest a
where a.year = (select max(b.year) from SubqueryTest b)
group by a.month
Run Code Online (Sandbox Code Playgroud)
当子查询被变量替换时,它会在 <1 秒内运行(执行计划):
declare @year float
select @year = max(b.year) from SubqueryTest b
select
month
, count(*)
from SubqueryTest where year = @year group by month
Run Code Online (Sandbox Code Playgroud)
从执行计划来看,“select max...”子选择对“SubqueryTest a:”中的数百万行中的每一行都运行,这就是为什么它需要这么长时间。
我的问题:由于子选择是标量、确定性且不相关,为什么查询优化器不执行我在第二个示例中所做的操作并运行子查询一次,存储结果,然后将其用于主查询?我确定我对 SQL Server 的理解只是一个漏洞,但我真的很想帮助填补它 - 用谷歌几个小时没有帮助。
该表刚超过 1GB,有近 2800 万条记录:
CREATE TABLE SubqueryTest(
[pk_id] [int] IDENTITY(1,1) NOT NULL
, [Year] [float] NULL
, [Month] [float] NULL …Run Code Online (Sandbox Code Playgroud) 我有一个从应用程序中使用的大视图。我想我已经缩小了我的性能问题,但我不确定如何解决它。视图的简化版本如下所示:
SELECT ISNULL(SEId + '-' + PEId, '0-0') AS Id,
*,
DATEADD(minute, Duration, EventTime) AS EventEndTime
FROM (
SELECT se.SEId, pe.PEId,
COALESCE(pe.StaffName, se.StaffName) AS StaffName, -- << Problem!
COALESCE(pe.EventTime, se.EventTime) AS EventTime,
COALESCE(pe.EventType, se.EventType) AS EventType,
COALESCE(pe.Duration, se.Duration) AS Duration,
COALESCE(pe.Data, se.Data) AS Data,
COALESCE(pe.Field, se.Field) AS Field,
pe.ThisThing, se.OtherThing
FROM PE pe FULL OUTER JOIN SE se
ON pe.StaffName = se.StaffName
AND pe.Duration = se.Duration
AND pe.EventTime = se.EventTime
WHERE NOT(pe.ThisThing = 1 AND se.OtherThing = 0)
) Z …Run Code Online (Sandbox Code Playgroud) 这个问题的一个例子表明,SQL Server 将选择全索引扫描来解决这样的查询:
select distinct [typeName] from [types]
Run Code Online (Sandbox Code Playgroud)
其中 [typeName] 有一个非聚集的、非唯一的升序索引。他的示例有 200M 行,但只有 76 个唯一值。在这种密度下,搜索计划似乎是更好的选择(约 76 次二进制搜索)?
他的情况可以正常化,但问题的原因是我真的想解决这样的问题:
select TransactionId, max(CreatedUtc)
from TxLog
group by TransactionId
Run Code Online (Sandbox Code Playgroud)
上有一个索引(TransactionId, MaxCreatedUtc)。
使用标准化源 (dt) 重写不会改变计划。
select dt.TransactionId, MaxCreatedUtc
from [Transaction] dt -- distinct transactions
cross apply
(
select Max(CreatedUtc) as MaxCreatedUtc
from TxLog tl
where tl.TransactionId = dt.TransactionId
) ca
Run Code Online (Sandbox Code Playgroud)
仅将 CA 子查询作为标量 UDF 运行确实显示了 1 次搜索的计划。
select max(CreatedUtc) as MaxCreatedUtc
from Pub.TransactionLog
where TransactionID = @TxId;
Run Code Online (Sandbox Code Playgroud)
在原始查询中使用该标量 UDF 似乎可行,但会失去并行性(UDF 的已知问题): …
我有 4 个表,让我们将它们命名为:
(kk - 表示数百万)
我有一个遗留查询,它是这样构造的:
select C.<some_fields>,B.<some_fields>,D.<some_fields> from C
inner join A on C.x = A.x
inner join D on D.z = 123 and D.a_id = A.a_id
inner join B on C.x = B.x and B.z = 123
where A.type = 'Xxx'
Run Code Online (Sandbox Code Playgroud)
此查询非常慢,执行结果最多需要 3 分钟(对于特定情况,它返回 35k 行)。
但是当我将其更改为以下结构时:
with t as (
select C.<some_fields>,D.<some_fields> from C
inner join A on C.x = A.x
inner join D …Run Code Online (Sandbox Code Playgroud) postgresql performance optimization execution-plan amazon-rds query-performance
(这篇文章的后续内容:当我在子查询中 ORDER BY 时,为什么我的 PostgreSQL 表达式索引没有被使用?)
PostgreSQL 9.5。
我不能透露全部细节,但table有 22 列和 5 个索引:
text(btree)text(btree)timestamp with time zone(btree)tsvector(杜松子酒)bigint(btree)(从上一篇文章你知道我试图避免创建这个额外的列,只是使用表达式索引——将两integer列加在一起——没有成功。bigint这里的列可能只是“整数”,但我做了一个创建它时出错;添加列、填充它并重新编制索引花了大约一个小时,所以我希望这不相关,但要提及它以防万一。)
除了tsvector.
以下查询都只需要 12ms 并且只使用一个Index Scan:
SELECT pk FROM table ORDER BY pk DESC LIMIT 10SELECT pk FROM table ORDER BY text_column DESC LIMIT 10SELECT pk FROM table ORDER BY timestamp_column DESC LIMIT 10 …postgresql performance index optimization postgresql-9.5 postgresql-performance
optimization ×10
performance ×4
mysql ×3
postgresql ×3
sql-server ×3
index ×2
innodb ×2
subquery ×2
amazon-rds ×1
distinct ×1
group-by ×1
index-tuning ×1
join ×1
myisam ×1
mysql-5.5 ×1
t-sql ×1