在 MySQL InnoDB 数据库中安排表的自动优化的最佳方法是什么?例如,我可以使用事件吗?我最近遇到了一个很大的性能问题(在查询时),其中一个表实际上是我数据库中最大的表,并且经常更新。我在表上运行OPTIMIZE后,问题就解决了。
我有一个查询,看起来像
SELECT *
FROM table0
WHERE id IN (SELECT id FROM table1 JOIN table2)
Run Code Online (Sandbox Code Playgroud)
Oracle 选择使用嵌套循环将 table0 与 (table1 x table2) 的结果连接起来,这需要几个小时。我试图弄清楚我是否可以暗示它使用 HASH 来代替,但不知道使用哪个提示以及在哪里使用。我尝试将 HASH_SJ 和 HASH_AJ 贴在各个地方,但没有帮助...
如何在 tmpfs 上设置 mysql?
我正在阅读法语教程,作者是这样做的:
1.) 创建一个 tmpfs 目录:
mkdir /var/tmpfs
mount -t tmpfs -o size=1G tmpfs /var/tmpfs
chown -R mysql:mysql /var/tmpfs/mysql
Run Code Online (Sandbox Code Playgroud)
2.) 将它添加到 fstab :
tmpfs /var/tmpfs tmpfs nodev,nosuid,noexec,noatime,size=1G 0 0
Run Code Online (Sandbox Code Playgroud)
3.) 将 MySQL 复制到 tmpfs(这里的 ramfs 是否正确?)
service mysql stop
cp -Rfv /var/lib/mysql /var/ramfs/
chown -R mysql:mysql /var/tmpfs/mysql
Run Code Online (Sandbox Code Playgroud)
4.) 编辑 /etc/my.cnf
datadir /var/tmpfs/mysql
Run Code Online (Sandbox Code Playgroud)
然后重新启动 mysqld,您可以选择添加启动/停止脚本以将 ram 数据备份到磁盘...
但我不确定以上是否正确:本教程的作者是否将 ramfs 误认为是 tmpfs?然后他继续在启动/停止脚本中使用 ramfs,但是 ramfs 必须在那里做什么,它真的只是 tmpfs 吗?
我读过那些本身并不总是做同样事情的过程,不会总是有一个好的计划。也就是说(如果我错了,请纠正我),如果我有一个过程,如果当天是偶数,它从表 X 中读取,否则它从表 Y 中读取,并且它第一次执行的时间是偶数,那么生成的计划将被优化对于从表 X 读取而不是从 Y 读取,即使从 Y 读取,sql 也会使用该计划,恕我直言很容易理解并尽量避免,但是作用于同一个表的过程呢。
像下面的示例(显然是一个非常简单的示例),如果它第一次运行,并且该项目确实存在,而随后的运行通常不存在(或反之亦然),我是否会得到一个“不太好”的计划这会影响性能?
CREATE PROCEDURE dbo.MyProc
(
@data VarChar(25),
@name VarChar(25)
)
AS
IF NOT EXISTS (SELECT * FROM dbo.MyTable WHERE myname = @name)
BEGIN
INSERT dbo.MyTable (myname, mydata)
VALUES (@name, @data)
END
ELSE
BEGIN
UPDATE dbo.MyTabel
SET mydata = @data
WHERE myname = @name
END
Run Code Online (Sandbox Code Playgroud) sql-server stored-procedures optimization execution-plan sql-server-2008-r2
我在 MySQL 表中使用全文索引,每次插入到该表中大约需要 3 秒。似乎 MySQL 在每次插入/更新后重建(一部分)全文索引。这是正确的吗?
该表有大约30varchar和text领域,在VARCHAR字段的一些指标,并通过三个域的全文索引title_text (char(255)), content_text (text), author_text (char(255))。表中大约有 210.000 行,表大小约为 2.5 GB,索引大小约为 0.5 GB。对每一个新行都执行插入查询(没有对所有插入的组合查询)。
我怎样才能从INSERT? 当 MySQL 重建全文索引时,是否有设置选项?
我创建了一个每晚运行的脚本,以根据碎片重建和重新组织索引,重建碎片 > 30% 的索引,重新组织碎片 10% - 30% 的索引。
运行脚本后,我注意到我们有大约 400 个索引仍然反映了 > 10% 的碎片计数,经过更多调查,我发现一些帖子提到页数 < 1000 的任何索引都不会被 SQL 重新组织.
我进一步调查了为什么我的脚本没有更新我的所有索引并发现查询的结果
sys.dm_db_index_physical_stats(DB_ID(DB_NAME()),NULL,NULL,NULL, 'DETAILED')
Run Code Online (Sandbox Code Playgroud)
对于具有 > 1 条记录的表,显示页数为 5、6,record_count 列有大约 16 000 条记录,然后我通过运行强制在索引上重建索引
ALTER INDEX [indexname] ON [schema].[table] REBUILD WITH (FILLFACTOR = 85, STATISTICS_NORECOMPUTE = OFF)
Run Code Online (Sandbox Code Playgroud)
我的索引现在显示 1 磨机 + 记录计数。
我的问题是:为什么重新组织他的索引不会纠正索引中的记录计数和碎片以及首先是什么导致此记录计数值在索引上变得如此过时?
我现在的计划是今晚强制重建所有索引,然后按照正常方式运行我的脚本。我是否应该担心索引记录计数再次过时?
假设一个人有一列单词,可以在其上建立BTREE索引:
CREATE TABLE myTable (
words VARCHAR(25),
INDEX USING BTREE (words)
);
LOAD DATA LOCAL INFILE '/usr/share/dict/words' INTO TABLE myTable (words);
Run Code Online (Sandbox Code Playgroud)
现在人们想要找到与某些搜索查询共享最长公共前缀的记录,例如'foobar'. 我想这样做:
SELECT DISTINCT words
FROM myTable
WHERE words LIKE CASE
WHEN NOT EXISTS (SELECT * FROM myTable WHERE words LIKE 'f%') THEN '%'
WHEN NOT EXISTS (SELECT * FROM myTable WHERE words LIKE 'fo%') THEN 'f%'
WHEN NOT EXISTS (SELECT * FROM myTable WHERE words LIKE 'foo%') THEN 'fo%'
WHEN NOT EXISTS (SELECT …Run Code Online (Sandbox Code Playgroud) 我有一个大表 ~2500 万行的结构
CREATE TABLE [dbo].[rx](
[pat_id] [int] NOT NULL,
[fill_Date] [date] NOT NULL,
[script_End_Date] AS (dateadd(day,[dayssup],[filldate])) persisted,
[drug_Name] [varchar](50) NULL,
[days_Sup] [int] NOT NULL,
[quantity] [float] NOT NULL,
[drug_Class] [char](3) NOT NULL,
CHECK(fill_Date <=script_End_Date
PRIMARY KEY NONCLUSTERED
(
[clmid]
)
create clustered index ix_rx_temporal on rx(fill_date asc, script_end_date asc, pat_id asc)
Run Code Online (Sandbox Code Playgroud)
永远不会查询此表上的主键。迄今为止,该表最常用于涉及日期范围的查询。我有一个带有结构的日历表
CREATE TABLE [dbo].[Calendar](
[cal_date] [date] PRIMARY KEY,
[Year] AS YEAR(cal_date) PERSISTED,
[Month] AS MONTH(cal_date) PERSISTED,
[Day] AS DAY(cal_date) PERSISTED,
[julian_seq] AS 1+DATEDIFF(DD, CONVERT(DATE, CONVERT(varchar,YEAR(cal_date))+'0101'),cal_date));
Run Code Online (Sandbox Code Playgroud)
我试图加速的查询是:
;WITH x …Run Code Online (Sandbox Code Playgroud) 我的服务器上有一个简单的 PHP 发送电子邮件脚本的问题,该脚本通过 cronjob 每分钟运行一次。该脚本包含一个在大多数情况下运行速度非常快的 MySQL 查询,但随机将“永远”运行。
感觉就像一个类似的问题:https : //stackoverflow.com/questions/976739/mysql-query-randomly-takes-forever
在运行 MySQL 查询时,在看似随机的时间里,我的服务器上的负载从平均 0.5 激增到 8,我的整个服务器慢慢地接近停止。查询最终会完成,但有时会运行超过 10 分钟——在“正常”情况下,查询会在 0.2 秒内完成。
这是查询:
SELECT * FROM email_messages
WHERE time_created <= "2013-04-22 10:40:00" AND is_sent = 0 AND is_cancelled = 0
LIMIT 6
Run Code Online (Sandbox Code Playgroud)
time_created 是(应该)索引 - 其目的是在发送前创建一个 10 分钟的延迟,以便在必要时取消电子邮件。
我已将其与此查询隔离,因为当此 cronjob 关闭时,我的服务器运行良好,而没有平均负载峰值。
我的服务器是具有 2GB RAM 的 VPS。数据库并不大(总共 750mb),但选择的 email_messages 表是迄今为止最大的,大约 400mb。
经过研究,我认为是MySQL查询缓存问题,因为打开了查询缓存。但是关闭查询缓存并没有解决问题。
我通过设置关闭了 query_cache query_cache_size = 0。
关于这里可能发生什么的任何想法?
[结论]
我做了一个实验,通过使用我的主键在查询中包含一个条件,以便只搜索最后 1000 个表条目。
... AND id > 131000 ...
Run Code Online (Sandbox Code Playgroud)
在这种情况下运行 cronjob 解决了这个问题,在 …
我目前正在汇总来自不同社交网络的帖子。目前我有来自 Facebook、Twitter、Youtube、Instagram 和 Pinterest 的 50-1 亿个帖子。
考虑一张桌子 posts
posts
{
id int(11),
user_id int(11),
url varchar(256),
image varchar(256),
source int(11), // Social Network Source
created bigint(20), // Publish time of the post
visible int(1) // Public or Private Posts
}
Run Code Online (Sandbox Code Playgroud)
使用 InnoDB
索引:
primary key on id
user_id,source
user_id,created
Run Code Online (Sandbox Code Playgroud)
空间使用
Type Usage
Data 45,876.0 MiB
Index 4,959.0 MiB
Total 50,835.0 MiB
Run Code Online (Sandbox Code Playgroud)
使用具有 7.5 GB RAM 的 Amazon RDS。
我正在执行的查询如下
select id
from posts
where user_id={user_id}
and visible=1
order by …Run Code Online (Sandbox Code Playgroud) optimization ×10
mysql ×6
index ×4
sql-server ×3
performance ×2
btree ×1
innodb ×1
join ×1
maintenance ×1
oracle ×1