在mysql 5.6中,考虑这 2 个在 A、B、C 和 D 之间创建关系的示例。
实施例1
CREATE TABLE `a` (
id INT UNSIGNED NOT NULL,
PRIMARY KEY (id)
) ENGINE = INNODB;
CREATE TABLE `b` (
id INT UNSIGNED NOT NULL,
a INT UNSIGNED NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (a) REFERENCES a (id) ON DELETE CASCADE
) ENGINE = INNODB;
CREATE TABLE `c` (
id INT UNSIGNED NOT NULL,
a INT UNSIGNED NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (a) REFERENCES a (id) …Run Code Online (Sandbox Code Playgroud) 我有一个大约有 3000 万行的表(很快就会增加两倍/三倍),我必须在其中进行定期更新。表结构如下:
id,
cookie_id VARCHAR(45),
country VARCHAR(45),
category VARCHAR(45),
other_non_relevant_columns
Run Code Online (Sandbox Code Playgroud)
索引看起来像这样:
SHOW INDEX FROM data;
+-------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| data | 0 | PRIMARY | 1 | id | A | 24767570 | NULL | NULL | | BTREE | | |
| data | 1 | cookie_index | 1 | cookie_id | …Run Code Online (Sandbox Code Playgroud) mysql performance delete explain mysql-5.7 query-performance
在 中mydatabase,有一个table1近 8M 行的表,从表中删除大约 7M 行后,数据库和表本身的大小保持不变。
桌子尺寸:
+---------------------------------------------+-----------+
| Table | Size (MB) |
+---------------------------------------------+-----------+
| Table1 | 96000 |
Run Code Online (Sandbox Code Playgroud)
删除查询:
DELETE FROM table1 WHERE foo < 'boo';
Query OK, 7809000 rows affected (43.25 sec)
Run Code Online (Sandbox Code Playgroud)
删除数据后的大小:
+---------------------------------------------+-----------+
| Table | Size (MB) |
+---------------------------------------------+-----------+
| Table1 | 96000 |
Run Code Online (Sandbox Code Playgroud)
知道为什么从该表中删除数据并没有减少数据库大小吗?
服务器版本:5.7.19-17-log Percona Server (GPL)
首先,可更新的 CTE、派生表或视图可以直接作为目标UPDATE,即使它具有多个基表,只要所有列都来自同一源表。
DELETE但即使仅选择一个表中的列,它们也不能成为 a 的目标。
Msg 4405 Level 16 State 1
View or function 'x' is not updatable because the modification affects multiple base tables.
Run Code Online (Sandbox Code Playgroud)
为了绕过这个限制,我尝试MERGE对虚拟表使用 a 。(显然,这个简单的示例可以使用DELETE...WHERE EXISTS或通过将一个表作为合并源来编写,但这一点是正确的。使用了原始示例,ROW_NUMBER因此这些是不可能的。)
WITH Joined AS (
SELECT t1.*
FROM t1
JOIN t2 ON t2.id1 = t1.id1
)
MERGE Joined
USING (VALUES(0)) v(dummy) ON 1=0
WHEN NOT MATCHED BY SOURCE THEN DELETE;
Run Code Online (Sandbox Code Playgroud)
这实际上是被允许的。但我发现被修改的表并不依赖于所选择的列或其顺序。这完全取决于表的连接顺序。
在我看来,这似乎是完全错误的行为。
实验THEN UPDATE显示了更明智的行为:它取决于子句中使用的列THEN UPDATE,与普通语句相同 …
是否可以通过一个请求清除所有表?我尝试了以下没有结果。
DELETE a,b,c,d,e,f,g,h,i,j,k,l,m,n,o
FROM jos_bet_details as a, jos_bet_1x2 as b, jos_bet_1x2_best as c, jos_bet_1x2_prev as d,
jos_bet_1x3 as e, jos_bet_1x3_best as f, jos_bet_1x3_prev g, jos_bet_hcp as h,
jos_bet_hcp_best i, jos_bet_hcp_prev j, jos_bet_ou k,jos_bet_ou_best l,
jos_bet_ou_prev m, jos_bet_debug n, jos_bet_deleted o
Run Code Online (Sandbox Code Playgroud) 我想问一下如何处理这种关系。为了更好地查看,我试图简化并将我的情况转换为我认为 StackOverflow 问题投票的方式(对不起,如果不是:-)

我想添加一个带有CASCADE DELETE规则的约束,但是我不知道这种情况是否可行。另一种选择是创建一个ON DELETE触发器,所以...
我的问题是:
你更喜欢CASCADE DELETE约束规则(如果可能的话)还是ON DELETE触发器?
或者你会为这个简单的案例(想象一下 StackOverflow 的投票方案)以不同的方式创建一个数据库模型吗?
我为什么要问:
我在某处读到CASCADE DELETE约束规则在内部只是触发器,而这里的一些人根本不喜欢约束规则。我知道,很模糊的问题,但我想让我的数据库从不存在的关系记录中清除。
重要的是:
我正在创建的应用程序应该能够在 SQL Server 以及 MySQL 数据库引擎上运行,但我猜这两者都应该支持所有CASCADE DELETE约束规则和ON DELETE触发器。
谢谢!
问题:我有一张很大的桌子 - 占用了高达 9.5 TB 的空间。我需要从中删除大约 500 万行。我想出的最好方法在 2 小时内删除了 100 万条记录!由于我无法在高峰时间运行此程序,因此我每天只有 2 小时的时间窗口,以这种速度删除 500 万行需要 4 个工作日。
问:我想知道 SQL Server 是否具有可以同时对一个表运行 2 个或多个删除的功能。可能类似于虚拟分区表 - 不确定。
我还想补充一点,运行我的脚本会导致页面锁定,但会阻止事务日志增长。我的脚本与 vonPryz 建议的脚本非常相似:
如何在不增加事务日志的情况下从大表中批量删除Greg M Lucas。
我做了一个例子来让我展示我的问题是什么:
设置:
CREATE TABLE [dbo].[Test](
[TestId] [bigint] IDENTITY(1,1) NOT NULL,
[ParentTestId] [bigint] NULL,
CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED ([TestId] ASC)
)
GO
ALTER TABLE [dbo].[Test] WITH CHECK ADD CONSTRAINT [FK_Test_ParentTest]
FOREIGN KEY([ParentTestId])
REFERENCES [dbo].[Test] ([TestId])
GO
ALTER TABLE [dbo].[Test] CHECK CONSTRAINT [FK_Test_ParentTest]
GO
DECLARE @iter INT
SET @iter = 1
WHILE @iter < 1000
BEGIN
INSERT INTO dbo.Test ( ParentTestId )
VALUES ( null ),( null ),( null ),( null ),( null ),( null ),( null ),( null ),
( …Run Code Online (Sandbox Code Playgroud) 我们在 SQL Server 2008 R2 标准服务器中有一个非常大的表,我通过将它们复制到单独磁盘上的另一个数据库中来存档行,然后使用 SSIS 数据流从原始表中删除它们。该表有一个 bigint 主键,并且正在按照该键的数字顺序删除行。然而,当我删除行时,表的整体索引大小正在稳步增加,我不知道为什么。在整个过程中,数据大小保持不变。
以下是表的详细信息:
行数:~300,000,000
数据大小:~65 GB
索引大小:~65 GB
行正在以每小时约 350,000 的速度被删除。
列定义使用以下数据类型:smallint、int、bigint、char、varchar、nvarchar、uniqueidentifier、bit、datetime
该表有一个主键,即表上的聚集键以及 4 个非聚集索引。
该表也是复制维护计划的一部分。表的复制副本的数据大小和索引大小都在减少!
上周我在另一个表上执行了相同的过程,当我删除行时,我可以看到该表的数据大小和索引大小都在减少。
在这种情况下,是否有任何解释为什么索引大小会不断上升?
我正在阅读这98-364 exam本书,但有一个问题我无法完全回答:
“您将使用什么命令从 Contact 表中删除所有没有美国国家/地区的记录,同时释放这些记录使用的空间?”
如果“没有美国的国家”不在那里,那么它只是“截断命令”,因为它会清除该表中的所有数据,并释放空间。据我所知,删除命令不会释放空间,而且我找不到在针对特定记录的同时删除和释放空间的命令。
这本书在这里有错别字吗?或者有没有人知道的命令?
注意:它是“什么命令...”,而不是命令。
编辑:(斯图尔特)这里有很多有用的答案,在我看来,这本书有些含糊不清。在“你会使用哪个命令”之外,如果考试中出现这种情况,“预期”答案是什么?我假设他们正在寻找“带有 where 子句的删除命令”。仅仅因为他们到目前为止,书中只建议了三种方法(删除/截断/删除)。
delete ×10
mysql ×5
sql-server ×5
foreign-key ×2
performance ×2
archive ×1
cascade ×1
constraint ×1
explain ×1
index ×1
innodb ×1
merge ×1
mysql-5.5 ×1
mysql-5.7 ×1
sql-standard ×1
ssis ×1
t-sql ×1
truncate ×1