摘要: 本人微信和易信公眾號: 微軟動態CRM專家羅勇 ,回復267或者20180311可方便獲取本文,同時可以在第一間得到我發布的最新的博文信息,follow me!我的網站是 www.luoyong.me 。
在Dynamics CRM中快速查找功能是個讓人喜歡的功能,在每個實體的列表界面的右上角有個搜索記錄的功能,輸入搜索關鍵字回車后就會執行搜索。

還有Dynamics 365的全局搜索功能也是對指定實體(系統管理員配置)執行快速查找並顯示結果。

用戶很喜歡快速查找功能,而且在實施項目過程中配置快速查找也很簡單,打開實體的類型為【快速查找視圖】的視圖,在彈出窗口中點擊【添加查找列】添加后保存並發布實體可以了。我這里將序列號 productserialnumber 添加為查找列后保存並發布【案例】實體。

快速查找功能配置簡單,用戶喜歡,那是不是配置的越多越好。有句廣告詞說的好,【勁酒雖好,可不要貪杯】。我這里就以一個實際例子來說明下一個快速查找列引發的【血案】。
如果某個實體的記錄比較多,比如數百萬行記錄以上,你添加了一個快速查找列,但是Dynamics 365的每天運行的維護作業(maintenance jobs)中的Indexing Management這個作業沒有在你添加快速查找列后運行為之添加索引的話,那就可能引發【血案】。使用這個大實體(記錄數很多)的快速查找功能,如果再加上對這個字段的值缺乏分析(比如新加字段),那么可能導致這個快速查找運行非常慢,乃至耗盡數據庫服務器的CPU,導致系統用起來非常緩慢甚至不可用(系統報錯)。這個可能很多人沒有碰到不會在意,希望看到本篇文章的童鞋們吸取教訓。
我這里拿一個快速查找的SQL來給大家看看,可以看到我添加的快速查找列 productserialnumber 加入了搜索(Like執行的搜索)中了。
exec sp_executesql N'WITH __QuickFind__ as (select top 10001 [IncidentId] from (
SELECT "incident0".[IncidentId] AS [IncidentId] FROM [IncidentBase] AS "incident0" WITH (NOLOCK)
where ("incident0".Title like @Title0) OR ("incident0".TicketNumber like @TicketNumber0) OR ("incident0".ProductSerialNumber like @ProductSerialNumber0)) as [__QuickFindInternal__])select
top 51 "incident0".PriorityCode as "prioritycode"
, "incident0".TicketNumber as "ticketnumber"
, "incident0".Title as "title"
, "incident0".CreatedOn as "createdon"
, "incident0".CaseOriginCode as "caseorigincode"
, "incident0".IncidentId as "incidentid"
, "incident0".ProcessId as "processid"
, "incident0".StateCode as "statecode"
, convert(bigint, "incident0".VersionNumber) as "versionnumber"
, case when (select COUNT(*) from [__QuickFind__]) = 10001 then 1 else 0 end as [__QuickFindLimitValue__]
, convert(bigint, "processidworkflowworkflowid".VersionNumber) as "processidworkflowworkflowid.versionnumber"
from
Incident as "incident0" WITH (NOLOCK) left outer join Workflow as "processidworkflowworkflowid" WITH (NOLOCK) on ("incident0".ProcessId = "processidworkflowworkflowid".WorkflowId)
where
[incident0].[IncidentId] in (select [IncidentId] from [__QuickFind__]) order by
"incident0".Title asc
, "incident0".IncidentId asc',N'@Title0 nvarchar(200),@TicketNumber0 nvarchar(200),@ProductSerialNumber0 nvarchar(200)',@Title0=N'0033%',@TicketNumber0=N'0033%',@ProductSerialNumber0=N'0033%'
既然能引發【血案】,那應該也有阻止【血案】的方法。管理上的改進咱不提了,本文提一下技術方面的三個建議:
- 按官方的建議是一個實體的快速查找列不要超過【六】個,不宜過多。
- 開發程序將本次要發布的內容和現有系統中的內容比較,查看是否增加了快速查找列。將要發布的解決方案用SDK\Bin目錄下的SolutionPackager.exe打開,然后比較實體定義文件中的快速查找列定義,看和之前的快速查找定義有啥不同,將不同的顯示出來,這樣不用去記錄本次部署增加了什么快速查找列(實際上也有可能會忘記增加了什么快速查找列)。這個技術上是可行的,我的項目已經在使用。
- 添加快速列后確保在用戶大規模使用前維護作業中Indexing Management這個作業會運行,這個作業會為快速查找列添加索引,很大程度上會避免問題。問題來了,這個作業什么時候運行,如何調整讓他運行?官方Darren Liu寫的博文CRM 2013 Maintenance Jobs 中有介紹(如果前面網址不好用了,用這個網址 https://darrenliu.wordpress.com/2014/04/03/crm-2013-maintenance-jobs/),遺憾的是文中並為提及如何查看以及更改下次運行時間。有個工具叫CRMJobEditor是可以看到和調整,可是調整到很近的時間不行。后來我們找到了靠譜的方法,直接改CRM數據庫中的如下記錄(注意如果一個部署中有多個組織,下面這個SQL會更新多條語句,請根據自己需要決定什么時候更新),運行完畢后,這條記錄的LastRunTime會變,LastResultCode也會變為0。如果還不放心可以看下是否為新加的快速查找列創建了索引,如下圖所示創建了。
一般先查出來,再修改,注意要修改兩個字段的值。
Select NextRunTime,RecurrenceStartTime,* from MSCRM_CONFIG.dbo.ScaleGroupOrganizationMaintenanceJobs where OperationType = 15然后再執行更改語句,一般不需要更改日期,更改時間就可以了,注意這里用的都是UTC時間,如果你是東八區,需要減去八個小時才是哦。
update MSCRM_CONFIG.dbo.ScaleGroupOrganizationMaintenanceJobs set NextRunTime = '2019-03-08 17:00:00',RecurrenceStartTime='2019-01-20 17:00:00' where OperationType = 15
-

-
- 很多朋友在問,OperationType字段值及其說明在哪兒查看?這個看實體System Job實體(架構名:AsyncOperation) 的 OperationType 字段的值。我這里簡單記錄如下:
-
Event
1
BulkEmail
2
Parse
3
Transform
4
Import
5
ActivityPropagation
6
PublishDuplicateRule
7
BulkDetectDuplicates
8
CollectSqmData
9
Workflow
10
QuickCampaign
11
PersistMatchCode
12
BulkDelete
13
DeletionService
14
IndexManagement
15
CollectOrgStats
16
ImportingFile
17
CalculateOrgStorageSize
18
CollectOrgDBStats
19
CollectOrgSizeStats
20
DatabaseTuning
21
CalculateOrgMaxStorageSize
22
BulkDeleteChild
23
UpdateStatisticIntervals
24
FullTextCatalogIndex
25
DatabaseLogBackup
26
UpdateContractStates
27
ShrinkDatabase // deprecated
28
ShrinkLogFile
29
ReindexAll
30
StorageLimitNotification
31
CleanupInactiveWorkflowAssemblies
32
RecurringSeriesExpansion
35
ImportSampleData
38
GoalRollup
40
AuditPartitionCreation
41
CheckForLanguagePackUpdates
42
ProvisionLanguagePack
43
OrgDBUpdate
44
SolutionUpdate
45
RefreshRowCountSnapshots
46
RefreshReadSharingSnapshots
47
OptInFcbOrgSync
48
PostToYammer
49
OutgoingActivity
50
IncomingEmailProcessing
51
MailboxTestAccess
52
EncryptionHealthCheck
53
ExecuteSdkMessage
54
SnapshotIsolationUpdate
55
UpdateEntitlementStates
56
IncrementalRollup
57
BootstrapRollup
58
ImportTranslations
59
CleanupOnRollupDelete
60
CheckFullTextIndexColumnStatus
61
ConvertDateAndTimeBehavior
62
EntityKeyIndexCreate
63
ReadCommittedSnapshotIsolationUpdate
64
UpdateKnowledgeArticleStates
65
AddOrgDBOptimization
66
RemoveOrgDBOptimization
67
ResourceBookingSync
68
ActionCardAsync
69
RefreshRowCountAndReadSharingSnapshots
70
CleanupSolutionComponentsOperation
71
AppModuleMetadataOperation
72
