sql-server – SQL Server – 处理嵌套的非确定性视图堆栈中字符串的本地化

在分析数据库时,我遇到了一个视图,该视图引用了一些非确定性函数,每个连接在此应用程序池中每分钟访问1000-2500次.视图中的简单SELECT产生以下执行计划:




这似乎是一个复杂的计划,一个不到一千行的视图,每隔几个月就会看到一行或两行.但随着以下其他纪念活动,情况会变得更糟:

>嵌套视图是非确定性的,因此我们无法对它们编制索引
>每个视图引用多个UDF来构建字符串
>每个UDF都包含嵌套的UDF,以获取本地化语言的ISO代码
>堆栈中的视图使用从UDF返回的其他字符串构建器作为JOIN谓词
>每个视图堆栈都被视为一个表,这意味着每个视图堆栈都有INSERT / UPDATE / DELETE触发器写入基础表
>视图上的这些触发器使用CURSORS EXEC存储过程,这些过程引用了更多这些字符串构建UDF.

这对我来说似乎很糟糕,但我只有几年的TSQL经验.它也变得更好!

看起来开发人员认为这是一个好主意,做了所有这些,以便存储的几百个字符串可以基于从特定于模式的UDF返回的字符串进行转换.

这是堆栈中的一个视图,但它们都同样糟糕:

CREATE VIEW [UserWKStringI18N]
AS
SELECT b.WKType,b.WKIndex,CASE
       WHEN ISNULL(il.I18NID,N'') = N''
       THEN id.I18NString
       ELSE il.I18nString
       END AS WKString,N'') = N''
       THEN id.IETFLangCode
       ELSE il.IETFLangCode
       END AS IETFLangCode,dbo.User3StringI18N_KeyValue(b.WKType,N'WKS') AS I18NID,dbo.UserI18N_Session_Locale_Key()  AS IETFSessionLangCode,dbo.UserI18N_Database_Locale_Key() AS IETFDatabaseLangCode
FROM   UserWKStringBASE b
LEFT OUTER JOIN User3StringI18N il
ON    (
il.I18NID       = dbo.User3StringI18N_KeyValue(b.WKType,N'WKS')
AND il.IETFLangCode = dbo.UserI18N_Session_Locale_Key()
)
LEFT OUTER JOIN User3StringI18N id
ON    (
id.I18NID       = dbo.User3StringI18N_KeyValue(b.WKType,N'WKS')
AND id.IETFLangCode = dbo.UserI18N_Database_Locale_Key()
)
GO

这就是为什么UDF被用作JOIN谓词的原因. I18NID列通过连接:STRING [ID | ID ]

在测试这些过程中,视图中的一个简单的SELECT返回~309行,并执行900-1400ms.如果我将字符串转储到另一个表中并在其上打一个索引,则相同的select将在20-75ms内返回.

所以,长话短说(我希望你对这种愚蠢行为表示赞赏)我希望成为一名优秀的撒玛利亚人,并为99%运行该产品的客户重新设计并重新编写此内容,而这些客户并未使用任何本地化 – 即使英语是第二/第三语言,即使用户也应使用[en-US]语言环境.

由于这是一个非正式的黑客攻击,我想到的是:

>创建一个新的String表,其中填充了原始基表中干净连接的数据集
>索引表格.
>在堆栈中创建一组替换的顶级视图,其中包括WKType和WKIndex列的NVARCHAR和INT列.
>修改引用这些视图的少数UDF,以避免某些连接谓词中的类型转换(我们最大的审计表是500-2,000M行,并在NVARCHAR(4000)列中存储INT,用于连接WKIndex列( INT).)
> Schemabind的观点
>向视图添加一些索引
>使用set logic而不是游标在视图上重建触发器

现在,我的实际问题:

>是否有通过视图处理本地化字符串的最佳实践方法?
>使用UDF作为存根有哪些替代方案? (我可以为每个架构所有者编写一个特定的VIEW并对该语言进行硬编码,而不是依赖于各种UDF存根.)
>通过完全限定嵌套UDF然后对视图堆栈进行模式绑定,可以简单地使这些视图成为确定性的吗?

解决方法

看一下给定的代码,我们可以说,

>首先,这不应该是一个视图,但它应该是一个存储过程,因为它不仅仅是从表中读取,而是使用UDF.
>其次,不应经常为同一列调用UDF.在这里,它在select中被调用一次

,N'WKS') AS I18NID

第二次加入

.IETFLangCode = dbo.User3StringI18N_KeyValue(b.WKType,N'WKS')

可以在临时表中生成值或使用CTE(公用表表达式)在连接发生之前首先获取这些值.

我已经生成了一个样本USP,它将提供一些改进:

CREATE PROCEDURE usp_UserWKStringI18N
AS
BEGIN
    -- Do operation using UDF 
    SELECT b.WKType,dbo.UserI18N_Session_Locale_Key() AS IETFSessionLangCode,dbo.UserI18N_Database_Locale_Key() AS IETFDatabaseLangCode
    INTO #tempTable
    FROM UserWKStringBASE b;

    -- Now final Select
    SELECT b.WKType,CASE 
            WHEN ISNULL(il.I18NID,N'') = N''
                THEN id.I18NString
            ELSE il.I18nString
            END AS WKString,N'') = N''
                THEN id.IETFLangCode
            ELSE il.IETFLangCode
            END AS IETFLangCode,b.I18NID,b.IETFSessionLangCode,b.IETFDatabaseLangCode
    FROM #tempTable b
    LEFT OUTER JOIN User3StringI18N il
        ON il.I18NID = b.I18NID
            AND il.IETFLangCode = b.IETFSessionLangCode
    LEFT OUTER JOIN User3StringI18N id
        ON id.I18NID = b.I18NID
            AND id.IETFLangCode = b.IETFDatabaseLangCode
END

请试试这个

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


本篇内容主要讲解“sqlalchemy的常用数据类型怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“sqlalche...
今天小编给大家分享一下sqlServer实现分页查询的方式有哪些的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家
这篇文章主要介绍“sqlmap之osshell怎么使用”,在日常操作中,相信很多人在sqlmap之osshell怎么使用问题上存在疑惑,小编查阅了各式资料,整理出
本篇内容介绍了“SQL注入的知识点有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧...
1. mssql权限sa权限:数据库操作,文件管理,命令执行,注册表读取等system。是mssql的最高权限db权限:文件管理,数据库操作等 users-administratorspublic权限:数据库操作 guest-users2、sql server注入执行命令查
sql执行计划如何查看?在SPL庞大的数据中我们不知道如何查看实际数据库中发生了什么事情,有必要定期进行查询优化和索引否则会影响我们后期的SQL的查询速度。那么针对这样的问题我们必须要知道SQL执行的计划,在本文中winwin7小编给大家分享下SQL执
SQL Server 是Microsoft 公司推出的关系型数据库管理系统。具有使用方便可伸缩性好与相关软件集成程度高等优点应用非常广泛。不过在使用中,我们会遇到非常多的错误,面对这么庞大的数据库环境,当然会有精确的错误代码的对照季,下面小编分享的
SQL Server本地账户无法登陆出现错误提示:error:40-Could not open a connenction to SQL Server的问题很常见,对于初学者来说可能不知道如何解决,一起来看看下面的解决方案。解决步骤如下:1、这种情况需要开启 SQL Server service
微软推出的SQL2008是一款非常好用的数据库软件,它稳定、功能强大,为众多企业提供了最佳的数据库解决方案,那么我们如何在Windows中安装它呢,一些朋友对SQL Server 2008的安装过程还不是很熟悉,下面就一起来看看SQL Server 2008详细安装图解...
本页概要如果您使用的是 SQL Server 2005备份和还原Sp_detach_db 和 Sp_attach_db 存储过程关于排序规则的说明导入和导出数据(在 SQL Server 数据库之间复
DBCC CHECKIDENT 检查指定表的当前标识值,如有必要,还对标识值进行更正。 语法 DBCC CHECKIDENT ( 'table_name' [ , { NORESEED
这里对 SQL Server 字符串函数进行分门别类地列出,便于查阅和记忆,相信大家都在其它方面有高深的编程基础,从字面上来说大家都知道这些函数的意义,就不对这些函数作过多的解释了,主要谈些经验,具体
查询及删除重复记录的方法 1、查找表(people)中多余的重复记录,重复记录是根据单个字段(peopleId)来判断select*frompeoplewherepeopleIdin(selectpe
微软发SQL Server 2008第二个CTP预览版from: http://news.csdn.net/n/20070807/107158.html8月7日消息,微软公司本周发布了SQL Serv
症状当您将数据库备份恢复到另一台服务器时,可能会遇到孤立用户的问题。SQL Server 联机丛书中的孤立用户疑难解答主题中没有讲述解决此问题的具体步骤。本文介绍了如何解决孤立用户问题。更多信息虽然术
当登录SQL Server 2005时可能碰到错误: 'No Process is on the Other End of the Pipe'。解决方法:(1)Open up SQL
概要本文描述如何映射标准登录和集成登录来解决在运行 SQL Server 的服务器之间移动数据库时的权限问题。更多信息当您将数据库从一个运行 SQL Server 的服务器移到另一个运行 SQL Se
----------------------------------------问题:该用户与可信的SQL SERVER 连接无关联使用sa用户或自建用户使用“SQL SERVER 身份认证”连接数据
更新日期: 2007 年 5 月 20 日 使用下表可以确定各种版本的 Microsoft SQL Server 2005 支持哪些功能。有关 SQL Server 2005 Enterprise E
当从Excel导入数据到Sql Sever中,可能会出现以下问题:
对于指定的缓冲区大小而言,源列的数据太大