0

我有桌子

Book: 
Id | Name |  ...

UrlRecord:  
Id | EntityId | Entityname | Slug  >> to store id-less url for many other tables like Category | Book | BookChapter...  

所以数据是巨大的

EntityId=> 包含其他表中的 Id,如 bookid、categoryid、chapterId...

Id EntityId    Entityname        Slug
1     2        Category      truyen-tranh
2     2        BookChapter    chapter-one

……

SearchBookDetails 存储过程:

SELECT p.Source,
    (SELECT Slug from UrlRecord url where EntityName = 'Category' and EntityId = (SELECT top(1) CategoryId from Book_Category_Mapping bc where bc.BookId = p.Id)
    ) as CategorySeName

FROM   ....

如果我有上面的 CategorySeName 子句,则性能非常慢,最多 22 秒,因为它是一个繁重的查询。

但是,我不知道如何提高性能并仍然像上面一样获得 CategorySeName 值返回。

4

2 回答 2

1

您的问题是相关的子查询。这是一种非常糟糕的技术,它将您的 select 语句更改为基本上是一个游标并逐行运行它。如果您有大量数据集,切勿使用它们。请改用派生表或 CTE 或临时表。

于 2013-07-10T13:48:52.793 回答
0

您使用 EntityId 指向其他 N 个表,例如 bookid、categoryid、chapterId。
你的表设计错了,实际上不可能设置外键。

这是错误的,因为这样你就不能强制使用外键。
更糟糕的是,这将导致查询性能变慢,因为没有像创建外键时那样自动创建索引。

查询优化器因此会提出一个非常丑陋的执行计划,这就解释了为什么它这么慢。

如果您必须有一个对象 id,您可以创建一个视图并执行以下操作:

COALESCE(bookid, categoryid, chapterId) AS EntityId 

但我非常怀疑 object_id 或你所说的 EntityId 对你有什么用处。

PS:

字符串比较而不是使用 id 总是一个坏主意

where EntityName = 'Category'

结合这两种反模式是一个特别好的主意。

于 2013-07-10T12:23:00.167 回答