我试图从表中查询 0 到 65,000 行。
服务器使用的是Microsoft SQL Server 2014,我无法更改服务器上的硬件。
架构
[Id] (PK) INT
[varchar1] VARCHAR(4) Normal Cardinality
[varchar2] VARCHAR(250) Normal Cardinality
[varchar3] VARCHAR(250) Normal Cardinality
[varchar4] VARCHAR(100) Normal Cardinality
[date1] DATETIME High Cardinality
[varchar5] VARCHAR(100) Low Cardinality
[varchar6] VARCHAR(1000) Normal Cardinality
[varchar7] VARCHAR(100) Normal Cardinality
[varchar8] VARCHAR(20) Normal Cardinality
[varchar9] VARCHAR(100) High Cardinality
[xml1] XML Low Cardinality
Run Code Online (Sandbox Code Playgroud)
询问
以下查询是存储过程的一部分(其余部分无关紧要,因为它对存储过程的性能影响不大)。列名称已替换为列类型和编号:
SELECT [varchar1]
, [varchar4]
, [date1]
, [varchar5]
, [varchar6]
, [varchar7]
, [varchar8]
, [varchar9]
, [xml1]
FROM [database].[dbo].[table] WITH …Run Code Online (Sandbox Code Playgroud) 我在工作中陷入了争论,我需要一些关于我可能忽略的可能陷阱的建议。
想象一下使用触发器将删除的记录复制到审计表的场景。触发器使用 SELECT *。每个人都指指点点,大喊大叫,告诉我们这有多糟糕。
但是,如果对主表的结构进行了修改,而忽略了审计表,那么触发器将产生一个错误,让人们知道审计表也需要修改。
该错误将在我们的 DEV 服务器上进行测试时被捕获。但是我们需要确保生产与 DEV 匹配,因此我们允许在生产系统中使用 SELECT * (仅限触发器)。
所以我的问题是:我被要求删除 SELECT *,但我不确定如何确保我们自动捕获这种性质的开发错误,任何想法或这是最佳实践?
我在下面整理了一个例子:
--Create Test Table
CREATE TABLE dbo.Test(ID INT IDENTITY(1,1), Person VARCHAR(255))
--Create Test Audit Table
CREATE TABLE dbo.TestAudit(AuditID INT IDENTITY(1,1),ID INT, Person VARCHAR(255))
--Create Trigger on Test
CREATE TRIGGER [dbo].[trTestDelete] ON [dbo].[Test] AFTER DELETE
NOT FOR REPLICATION
AS
BEGIN
SET NOCOUNT ON;
INSERT dbo.TestAudit([ID], [Person])
SELECT *
FROM deleted
END
--Insert Test Data into Test
INSERT INTO dbo.Test VALUES
('Scooby')
,('Fred')
,('Shaggy')
--Perform a …Run Code Online (Sandbox Code Playgroud) 我有一个简单的测试表,如下所示:
CREATE TABLE MyTable (x INT);
Run Code Online (Sandbox Code Playgroud)
在事务中,我尝试添加一列,然后插入到新创建的列中:
BEGIN TRANSACTION;
PRINT 'Adding column, ''SupplementalDividends'', to MyTable table.';
ALTER TABLE MyTable
ADD SupplementalDividends DECIMAL(18,6);
PRINT 'Column added successfully....';
PRINT 'Ready to INSERT into MyTable ...';
INSERT INTO MyTable (x, SupplementalDividends)
VALUES (1, 3.2);
PRINT '**** CHANGES COMPLETE -- COMMITTING.';
COMMIT TRANSACTION;
Run Code Online (Sandbox Code Playgroud)
当我运行上面的代码时,问题是一条错误消息:
Invalid column name 'SupplementalDividends'.
Run Code Online (Sandbox Code Playgroud)
为什么这会导致错误?如果我在交易之外的不同批次中添加该列,它将起作用。我的问题是我想在事务中添加列。为什么会出错?
当我运行以下查询时
select distinct A.movieID, A.avgStars from
(select mID as movieID, avg(stars) as avgStars
from Rating
group by mID) A
where A.avgStars <= all(select A.avgStars from A);
Run Code Online (Sandbox Code Playgroud)
我收到错误“无效的对象名称‘A’。”
你知道我为什么会得到这个吗?
谢谢!
当我查看一些查询的实际执行计划时,我注意到 WHERE 子句中使用的文字常量显示为计算标量和常量 scan的嵌套链。
为了重现这一点,我使用下表
CREATE TABLE Table1 (
[col1] [bigint] NOT NULL,
[col2] [varchar](50) NULL,
[col3] [char](200) NULL
)
CREATE NONCLUSTERED INDEX IX_Table1 ON Table1 (col1 ASC)
Run Code Online (Sandbox Code Playgroud)
里面有一些数据:
INSERT INTO Table1(col1) VALUES (1),(2),(3),
(-9223372036854775808),
(9223372036854775807),
(2147483647),(-2147483648)
Run Code Online (Sandbox Code Playgroud)
当我运行以下(废话)查询时:
SELECT a.col1, a.col2
FROM Table1 a, Table1 b
WHERE b.col1 > 2147483648
Run Code Online (Sandbox Code Playgroud)
我看到它将在索引查找和标量计算(来自常量)的结果中执行嵌套循环绘图。
请注意,文字大于 maxint。它确实有助于编写CAST(2147483648 as BIGINT). 知道为什么 MSSQL 将其推迟到执行计划中,并且有没有比使用强制转换更短的方法来避免它?它是否也会影响到准备好的语句(来自 jtds JDBC)的绑定参数?
标量计算并不总是完成(似乎是索引查找特定的)。有时查询分析器不会以图形方式显示它,而是col1 < scalar(expr1000)在谓词属性中显示它。
我已经在 Windows 7 上的 MS SSMS 2016 …
是否有任何脚本可以像活动监视器一样获取输出?
或者当活动监视器显示在屏幕上时,我可以使用哪些 DMV 来获取输出?
它应该能够显示存储过程名称以及当前正在运行的存储过程中的语句以及与块相关的信息。
我有一个在 SQL-Server 2012 DBMS 上运行的数据库。考虑到运行 SQL Server 的服务器不是网络域的一部分。当我执行这个 sql 命令时
ALTER DATABASE myDatabase SET TRUSTWORTHY ON;
Run Code Online (Sandbox Code Playgroud)
服务代理队列(早期设置和工作)接收消息,但与队列关联的活动存储过程没有启动。消息继续流入队列,但没有其他任何事情发生。在 SQL SERVER 日志中,我发现了这条消息
在队列“proofSCHEMA.myQueue”上运行的激活过程“proofSchema.mySP”输出以下内容:“主数据库中记录的数据库所有者 SID 与数据库“myDatabase”中记录的数据库所有者 SID 不同。您应该通过使用 ALTER AUTHORIZATION 语句重置数据库“myDatabase”的所有者来纠正这种情况。
如果我在网络域内的机器上运行相同的配置,则一切正常。
我不明白发生了什么以及为什么值得信赖的使用服务代理队列。
PostgreSQL 支持DOMAIN规范,来自 SQL 2011 工作草案规范,
域是命名的用户定义对象,可以在某些可以指定数据类型的地方将其指定为数据类型的替代。域由数据类型、可能是默认选项和零个或多个(域)约束组成。
这使我们能够做一些非常酷的事情,例如通过不区分大小写的文本类型为电子邮件实现HTML5 规范的域。它确保所有访问数据库的客户端都对插入的数据进行完整性检查。
CREATE DOMAIN email AS citext
CHECK ( value ~ '^[a-zA-Z0-9.!#$%&''*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$' );
Run Code Online (Sandbox Code Playgroud)
SQL Server 是否支持触发器系统之外的任何此类功能?
我们创建了一个 Windows 故障转移群集,然后添加了两个 SQL Server 实例作为 SQL Server 故障转移群集的节点。
我们在 SQL 配置管理器中将服务器设置为使用“AlwaysOn 可用性组”。
为了测试故障转移,我加载并运行了一个长查询,然后通过使用故障转移群集管理器停止活动节点上的群集服务来关闭活动节点。
查询在没有连接的情况下中断,在节点耗尽和新节点接管之前,服务器在大约 20 秒内显示为不可用。
我做错了吗?我应该如何配置它以便几乎没有连接丢失?
AlwaysOn 不是一直开启吗?
我正在与具有多个数据库的客户合作。有几个master级别数据库与instance级别数据库(特定于应用程序的 DB)有关系。从instanceto的关系master是整数值,表示master. 中的视图和存储过程instances设置为master通过这些存储的键加载数据。
显然,没有真正的参照完整性,但这是不好的做法还是数据应该驻留在instance数据库的只读表中?
sql-server best-practices referential-integrity multi-tenant
sql-server ×10
t-sql ×4
cast ×1
datatypes ×1
domain ×1
failover ×1
multi-tenant ×1
security ×1
sql-clr ×1
sql-standard ×1