0

大數我們有一個asp.net核心的網站,該網站處理用戶搜索如下:搜索查詢不處理用戶

public async Task<ICollection<UserSearchResult>> SearchForUser(string name, int page) 
    { 
     return await db.ApplicationUsers.Where(u => u.Name.Contains(name) && !u.Deleted && u.AppearInSearch) 
             .OrderByDescending(u => u.Verified) 
             .Skip(page * recordsInPage) 
             .Take(recordsInPage) 
             .Select(u => new UserSearchResult() 
             { 
              Name = u.Name, 
              Verified = u.Verified, 
              PhotoURL = u.PhotoURL, 
              UserID = u.Id, 
              Subdomain = u.Subdomain 
             }).ToListAsync(); 
    } 

查詢轉換爲類似下面的內容:

SELECT [t].[Name], [t].[Verified], [t].[PhotoURL], [t].[Id], [t].[Subdomain] FROM (SELECT [u0].*  FROM [AspNetUsers] AS [u0]  WHERE (((CHARINDEX('khaled', [u0].[Name]) > 0) OR ('khaled' = N'')) AND ([u0].[Deleted] = 0)) AND ([u0].[AppearInSearch] = 1)  ORDER BY [u0].[Verified] DESC  OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY ) AS [t] 

在客戶端,我們預讀取和警犬如下:

engine = new Bloodhound({ 
     identify: function (user) { 
      return user.UserID; 
     }, 
     queryTokenizer: Bloodhound.tokenizers.whitespace, 
     datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'), 
     dupDetector: function (a, b) { return a.UserID === b.UserID; }, 
     remote: { 
      cache: false, 
      url: '/account/Search?name=%QUERY&page=0', 
      wildcard: '%QUERY' 
     } 
    }); 

,我們配置的預輸入如下:

$('#demo-input').typeahead(
    { 
     hint: $('.Typeahead-hint'), 
     menu: $('.Typeahead-menu'), 
     minLength: 3, 
     classNames: 
     { 
      open: 'is-open', 
      empty: 'is-empty', 
      cursor: 'is-active', 
      suggestion: 'Typeahead-suggestion', 
      selectable: 'Typeahead-selectable' 
     } 
    }, 
    { 
     source: engineWithDefaults, 
     displayKey: 'name', 
     templates: 
     { 
      suggestion: template, 
      empty: empty, 
      footer: all 
     }, 
     limit: 5 
    }) 

該搜索只能在本地主機上找到,並且查詢作爲sql查詢運行良好。 我也在「已驗證」上創建了一個索引,並將速度降至1秒或更短。

我們的網站擁有數百萬註冊用戶,問題是隻要我們爲所有用戶提供搜索服務,Azure上的DTU百分比就會達到100%,並且查詢超時。 我們也有一個redis緩存來加速類似的查詢,但這並沒有幫助我們解決這個問題。

您的支持表示讚賞:)

+0

您還可以使用全文搜索 – TheGameiswar

+0

@ TheGameiswar可以請您進一步解釋嗎?也許加入它作爲答案? – Techy

+0

請在這裏檢查,您需要使用基於查詢的全文搜索,我們有一個學習應用程序,我們使用它來呈現基於用戶輸入的部分字符串的結果:https://www.simple-talk.com/sql/learn-sql-server/understanding-full-text -indexing -in -sql-server/ – TheGameiswar

回答

0

這很可能是u.Name.Contains(name)CHARINDEX('khaled', [u0].[Name]) > 0將要掃描整個表,或者在最好的指數。這將是緩慢的,你可以做的事情不多。

如果您對deletedappearInSearch有很大的偏見,您可能可以使用條件索引,但這些類型的搜索速度非常慢。你將需要一些特殊的結構來完成這項工作。

+0

我看到...但其他網站如何能夠實現這一點,甚至更大的負載,因爲我有網站工作沒有問題的低負載,但我需要一個解決方案來實現這一點。謝謝 – Techy

+0

如果你只能在名字的開頭匹配,那麼你可以嘗試索引'name'並使用'StartsWith',它會翻譯成'NAME LIKE'Khaled%''。除此之外,您需要查看非SQL解決方案或創建用戶名的所有部分,kha,hal,ale等,然後搜索。它很快變得艱難而複雜。 – LoztInSpace

+0

我不能僅在我的情況下使用startsWith。恐怕你解釋的另一種方式甚至會導致更多的數據庫調用。謝謝。 – Techy