标签: optimization

为什么 CBO 不选择没有统计数据的低成本跳过扫描?

在下面的脚本中,CBO 选择INDEX FAST FULL SCAN了一个INDEX SKIP SCAN(这通过使用 UNION ALL 的查询来说明,但您可以证明它是正确的,只需explain plan for select * from foo where baz=1)。尽管跳过扫描是成本较低的选择,但还是做出了这一选择。

一旦表被分析,跳过扫描是首选(尽管相对成本实际上上升)。CBO 似乎根本不考虑使用动态采样进行跳过扫描,这是真的吗?如果没有,为什么在收集统计数据之前没有选择跳过扫描?

架构:

create table foo( bar integer, 
                  baz integer, 
                  qux char(99), 
                  constraint pk_foo primary key (bar, baz) )
             organization index compress;
--table FOO created.
insert into foo(bar,baz) select mod(level,1000), level from dual connect by level<1000000;
--999,999 rows inserted.
commit;
--committed.
Run Code Online (Sandbox Code Playgroud)

预分析:

explain plan for
select * from foo where baz=1
union all
select …
Run Code Online (Sandbox Code Playgroud)

oracle optimization oracle-11g-r2

5
推荐指数
1
解决办法
429
查看次数

操作系统重启后,MySQL 查询速度慢 10 到 100 倍

我有一个在 Ubuntu 上运行的 MySQL 服务器。如果我重新启动 MySQL,一切都很好。但是,如果我重新启动操作系统,我的查询时间会增加 10 到 100 倍。我发现的问题的唯一“解决方案”是optimize在每张桌子上运行。之后一切又恢复正常。然而,在每次操作系统重启后重建整个数据库显然是极其痛苦的,而且不是一个可行的长期解决方案。

我通过以下方式重新启动操作系统

  1. 停止所有查询数据库的程序
  2. 等待查询完成执行
  3. 跑步 stop mysql
  4. 确保服务器停止ps -C mysqlps -C mysqld
  5. 跑步 reboot

如果我不重启操作系统并再次启动 MySQL,一切都很好。

附加信息:

  • 错误日志不包含任何指向问题的内容,我也没有收到任何错误。一切都只是慢了一两个数量级。
  • 所有表都受到影响。我正在使用 InnoDB,但在使用 MyISAM 时也存在同样的问题。
  • 通常 MySQL 使用 8GB RAM 的 80%,但在操作系统重新启动后仅使用大约 1GB。CPU 使用率从一个内核的 30-80% 下降到大约 1%。
  • 优化查询可以正常使用完整的 80% RAM,CPU 也会上升到正常值。

眼镜:

  • MySQL 5.5.35-0ubuntu0.12.04.2
  • Ubuntu 12.04.4 LTS
  • 8GB 内存,4 个 CPU 内核

my.cnf 文件:

[client]
port        = 3306
socket      = /var/run/mysqld/mysqld.sock

[mysqld_safe]
socket      = /var/run/mysqld/mysqld.sock
nice        = 0

[mysqld] …
Run Code Online (Sandbox Code Playgroud)

mysql performance optimization ubuntu query-performance

5
推荐指数
1
解决办法
3766
查看次数

找到与我口味最接近的用户

我试图用 SQL 编写以下要求:

每个用户都可以根据自己的喜好对电影进行评分。(1=我不喜欢,5=我喜欢它)并且系统应该向当前用户提供他尚未评分但其他用户也喜欢的电影列表。

为简化起见,我有这张表和以下数据:

create table wich (
  uid int,
  film varchar(50),
  rate int
);

insert into wich values 
(1, 'usual suspect', 5), (1, 'gataca', 4), (1, 'goldeneye', 2),
(2, 'usual suspect', 4), (2, 'gataca', 5), (2, 'i am a legend', 4), (2, 'the hobbit', 1),
(3, 'usual suspect', 1), (3, 'gataca', 5), (3, 'goldeneye', 5),
(4, 'usual suspect', 5), (4, 'goldeneye', 5),
(5, 'usual suspect', 5), (5, 'gataca', 4), (5, 'goldeneye', 5),
(6, 'usual suspect', 4), (6, 'gataca', …
Run Code Online (Sandbox Code Playgroud)

mysql optimization query-performance

5
推荐指数
1
解决办法
197
查看次数

DB事务日志最好的存储设备是什么?

我正在将 MySQL 与 InnoDB 存储引擎一起使用。事务日志放置在专用硬盘上。atopsar由于大量的小 IO(每秒大约 50 次写入,每个 6Kb),HDD仍然显示出这个 HDD 的大负载(> 50%)。

设置innodb_flush_log_at_trx_commit为 2 解决了问题,现在平均加载 5%。但是,MySQL 文档说:

当值为 2 时,日志缓冲区会在每次提交时写入文件,但不会对其执行刷新到磁盘操作。但是,当值为 2 时,每秒也会刷新日志文件一次。

值为 2 时,只有操作系统崩溃或断电才能擦除最后一秒的事务。

因此,可能会丢失最后一秒的事务日志。

我没有为 DB 服务器进行硬配置的经验,因此想知道存在哪些现代解决方案并且最适合 DB 的事务日志,提供可靠性和高 IO 能力。

通过the best我的意思是不同的变种,但个人更喜欢性能/价格的最佳组合。无论如何,我认为在这里收集不同的变体会很棒。

我知道通常的答案是“使用 SSD”,但我知道它的存储原则不是事务日志的可靠解决方案,它应该相对较快地失败。乍一看,现代 SSD 的重写次数似乎足以运行多年。但是,据我所知,SSD 按块重写数据,例如,如果您想写入 1b 的数据,SSD 将重写整个块,可能是 4Kb。因此,对于 1 个事务日志重写电路,SSD 可能会多次重写其块。

在我看来,理想的存储设备将是电池+RAM+HDD的组合,并且尺寸相对较小(大约5Gb或更小)。在正常操作中仅使用 RAM,断电时会将所有数据刷新到 HDD。它应该在一个设备中,而不是软件解决方案。但是,我不知道它们是否存在。

mysql performance optimization transaction-log

5
推荐指数
1
解决办法
266
查看次数

查询看起来最佳,但逻辑读取量很大

我在 SQL Server 中运行以下(非常简单)查询:

    SELECT MAX(PK_Field1)
    FROM MainTable kh
    WHERE kh.PK_Field1 >= '2014-12-01T00:00:00'
    AND kh.PK_Field2 = 1572
    AND kh.PK_Field3= 'FD5BF2F3-8ED7-479C-A71F-D04E4288CBFC'
Run Code Online (Sandbox Code Playgroud)

我从中得到了这些统计数据:

Table 'MainTable'. Scan count 9, logical reads 31078, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 171 ms,  elapsed time = 44 ms.
Run Code Online (Sandbox Code Playgroud)

虽然经过的时间并不多,但这个查询每十分钟执行大约一千次,所以超过 30k 的逻辑读取对我来说似乎不是很理想。但是,该表中的主索引的设计方式使这样的查询可以充分利用它。表 MainTable 包含以下内容:

PK_Field1 datetime
PK_Field2 int
PK_Field3 uniqueidentifier
Another_Field datetime
Run Code Online (Sandbox Code Playgroud)

该表不包含其他列,它有 300 万条记录,唯一的索引是 PK 字段上的聚集索引(与表中定义的顺序相同,按 ASC …

performance sql-server optimization query-performance

5
推荐指数
1
解决办法
1331
查看次数

Postgres:将旧记录迁移到单独的表并创建新的聚合记录是提高搜索速度的好策略吗?

我有一张包含 100 万条记录的表格。每次针对每种类型的事件(有很多)发生事件时,每天都会创建和更新新记录。我经常需要在许多记录中找到总和,并且执行这些查询的时间逐渐变慢,即使在某些地方有多个索引。由于现在存储了几年的数据,我正在考虑将超过 6 个月的记录迁移到单独的“存档”表,并为每个事件类型创建新记录,其中包括每月聚合(即行的总和)在 2014 年 1 月存储的 31 条记录中,将存储在 1 条记录中)。这有望提高搜索速度,但有更好的策略吗?这种归档方式常见吗?

postgresql optimization compression archive query-performance

5
推荐指数
1
解决办法
402
查看次数

我需要创建一个数据透视表还是可以更改此查询

我编写的以下查询在一定程度上起作用。我发现的问题是,在每个泵中,电缆等都可以在每个零件列中列出。例子:

在此处输入图片说明

我想得到的是列有每个泵、电缆等的井,而不是我目前得到的只是第一个泵、电缆等。

这是我正在运行的查询:

        With CTE AS(
SELECT Pull_Date, Well_Name, Part1 Part, Part1_PN PartPN, Part1_SN PartSN FROM testtest
UNION ALL
    SELECT Pull_Date, Well_Name, Part2, Part2_PN, Part2_SN from testtest
UNION ALL
    SELECT Pull_Date, Well_Name, Part3, Part3_PN, Part3_SN from testtest
)

Select Pull_Date, Well_Name,
    MIN(CASE WHEN Part='BODH' THEN 'BODH' ELSE NULL END) [BODH],
    MIN(CASE WHEN Part='BODH' THEN PartPN Else NULL END) BODH_PN,
    MIN(CASE WHEN Part='BODH' THEN PartSN ELSE NULL END) BODH_SN,
    MIN(CASE WHEN Part='Cable' THEN 'Cable' ELSE NULL END) [Cable],
    MIN(CASE WHEN Part= …
Run Code Online (Sandbox Code Playgroud)

optimization pivot t-sql

5
推荐指数
1
解决办法
102
查看次数

如何降低“Created_tmp_disk_tables” - 在磁盘上创建的临时表计数?

我有一个 ubuntu,mysql 5.6 DB,它被成千上万的用户大量使用。运行 10 天后,我有以下值:

| Created_tmp_disk_tables | 894170 |
| Created_tmp_files       | 26068  |
| Created_tmp_tables      | 914511 |
Run Code Online (Sandbox Code Playgroud)

我的配置值是:

| tmp_table_size | 268435456 |
| max_heap_table_size | 1073741824 |
Run Code Online (Sandbox Code Playgroud)

当我有 tmp_table_size = 16MB 和 max_heap_table_size=16MB 时,它是一样的。比我将其更改为 tmp_table_size = 256MB 和 max_heap_table_size = 1GB 但 Created_tmp_disk_tables 并没有停止增长。率是完全一样的。

我有 26GB 的堆。所有表都是 INNODB。

我错过了什么?

谢谢

mysql optimization

5
推荐指数
2
解决办法
1万
查看次数

帮助优化删除语句

使用 SQL Server 2012 Standard - 我正在根据另一个表的内容对一个表进行删除。这花费了相当长的时间(5 小时)并且对我来说似乎不是最佳选择,希望能提供一些优化语句的输入:

delete from [dbo].[tbl1]
where exists (
    select *
    from [dbo].[tbl2] t 
    where [dbo].[tbl1].[col1] = t.[col1]
    and [dbo].[tbl1].[col2] = t.[col2]
    and [dbo].[tbl1].[col3] = t.[col3]  
)
Run Code Online (Sandbox Code Playgroud)

各列如下:

tbl1.col1 varchar(10)
tbl1.col2 datetime
tbl1.col3 varchar(60)
tbl2.col1 varchar(10)
tbl2.col2 datetime
tbl2.col3 varchar(30)
Run Code Online (Sandbox Code Playgroud)

我意识到数据类型 col3不同,我知道这很糟糕,但这是否意味着无法使用索引?

每个表上都有一个非唯一聚集索引(此查询未涵盖)和两个表上的非聚集索引,涵盖 where 子句中包含的所有三列。

tbl1包含约 12 亿行,tbl2包含约 3000 万行。我预计将从中删除大约 3000 万行tbl1

任何帮助表示赞赏!

编辑:仅供参考,tbl1并且tbl2位于不同的文件组上,但位于同一个磁盘 (SAN) 上。另外,这里是执行计划:

执行计划

sql-server delete optimization sql-server-2012

5
推荐指数
1
解决办法
137
查看次数

我应该把这张大桌子分成三个小桌子吗?

我正在设计一个 PostgreSQL 数据库,该数据库将包含有关我的用户上传的照片的信息。所有用户都将拥有至少一张主照片和可选的一张或多张公开和/或私人照片。我的第一个架构如下:

user
----
id (PK)

photo
-----
id (PK)
user_id   (FK to user)
photo_id  (unique identifier such as "aK1q9")
type      ("main" or "other")
access    ("public" or "private")
Run Code Online (Sandbox Code Playgroud)

最常运行的查询是:

SELECT p.photo_id FROM photo p INNER JOIN user u ON p.user_id = u.id WHERE p.type = 'main' AND u.id = (some user id);
Run Code Online (Sandbox Code Playgroud)

下一个最受欢迎的查询将是:

SELECT p.photo_id FROM photo p INNER JOIN user u ON p.user_id = u.id WHERE p.type = 'other' AND p.access = 'public' AND u.id = (some user …
Run Code Online (Sandbox Code Playgroud)

postgresql performance database-design optimization query-performance

5
推荐指数
1
解决办法
2651
查看次数