diff --git a/CHANGES.md b/CHANGES.md
index 317684fad16..4f05a4b88ee 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -15,6 +15,7 @@ Apollo 1.10.0
 * [Fix issue: ingress syntax](https://github.com/apolloconfig/apollo/pull/3933)
 * [refactor: let open api more easier to use and development](https://github.com/apolloconfig/apollo/pull/3943)
 * [feat(scripts): use bash to call openapi](https://github.com/apolloconfig/apollo/pull/3980)
+* [Support search by item](https://github.com/apolloconfig/apollo/pull/3977)
 
 ------------------
 All issues and pull requests are [here](https://github.com/ctripcorp/apollo/milestone/8?closed=1)
diff --git a/apollo-adminservice/src/main/java/com/ctrip/framework/apollo/adminservice/controller/NamespaceController.java b/apollo-adminservice/src/main/java/com/ctrip/framework/apollo/adminservice/controller/NamespaceController.java
index 70c44779730..2823ce5c082 100644
--- a/apollo-adminservice/src/main/java/com/ctrip/framework/apollo/adminservice/controller/NamespaceController.java
+++ b/apollo-adminservice/src/main/java/com/ctrip/framework/apollo/adminservice/controller/NamespaceController.java
@@ -19,9 +19,13 @@
 import com.ctrip.framework.apollo.biz.entity.Namespace;
 import com.ctrip.framework.apollo.biz.service.NamespaceService;
 import com.ctrip.framework.apollo.common.dto.NamespaceDTO;
+import com.ctrip.framework.apollo.common.dto.PageDTO;
 import com.ctrip.framework.apollo.common.exception.BadRequestException;
 import com.ctrip.framework.apollo.common.exception.NotFoundException;
 import com.ctrip.framework.apollo.common.utils.BeanUtils;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
 import org.springframework.web.bind.annotation.DeleteMapping;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
@@ -87,6 +91,18 @@ public NamespaceDTO get(@PathVariable("namespaceId") Long namespaceId) {
     return BeanUtils.transform(NamespaceDTO.class, namespace);
   }
 
+  /**
+   * the returned content's size is not fixed. so please carefully used.
+   */
+  @GetMapping("/namespaces/find-by-item")
+  public PageDTO<NamespaceDTO> findByItem(@RequestParam String itemKey, Pageable pageable) {
+    Page<Namespace> namespacePage = namespaceService.findByItem(itemKey, pageable);
+
+    List<NamespaceDTO> namespaceDTOS = BeanUtils.batchTransform(NamespaceDTO.class, namespacePage.getContent());
+
+    return new PageDTO<>(namespaceDTOS, pageable, namespacePage.getTotalElements());
+  }
+
   @GetMapping("/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName:.+}")
   public NamespaceDTO get(@PathVariable("appId") String appId,
                           @PathVariable("clusterName") String clusterName,
diff --git a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/repository/ItemRepository.java b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/repository/ItemRepository.java
index 572569e2e7c..f8ff6894139 100644
--- a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/repository/ItemRepository.java
+++ b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/repository/ItemRepository.java
@@ -18,6 +18,8 @@
 
 import com.ctrip.framework.apollo.biz.entity.Item;
 
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.repository.PagingAndSortingRepository;
@@ -35,6 +37,8 @@ public interface ItemRepository extends PagingAndSortingRepository<Item, Long> {
 
   List<Item> findByNamespaceIdAndDataChangeLastModifiedTimeGreaterThan(Long namespaceId, Date date);
 
+  Page<Item> findByKey(String key, Pageable pageable);
+  
   Item findFirst1ByNamespaceIdOrderByLineNumDesc(Long namespaceId);
 
   @Modifying
diff --git a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/repository/NamespaceRepository.java b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/repository/NamespaceRepository.java
index 29755bb636d..331d8cf31ef 100644
--- a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/repository/NamespaceRepository.java
+++ b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/repository/NamespaceRepository.java
@@ -24,6 +24,7 @@
 import org.springframework.data.repository.PagingAndSortingRepository;
 
 import java.util.List;
+import java.util.Set;
 
 public interface NamespaceRepository extends PagingAndSortingRepository<Namespace, Long> {
 
@@ -39,6 +40,8 @@ public interface NamespaceRepository extends PagingAndSortingRepository<Namespac
 
   List<Namespace> findByNamespaceName(String namespaceName, Pageable page);
 
+  List<Namespace> findByIdIn(Set<Long> namespaceIds);
+
   int countByNamespaceNameAndAppIdNot(String namespaceName, String appId);
 
 }
diff --git a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/ItemService.java b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/ItemService.java
index 127f14e0c4d..39ade331f0c 100644
--- a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/ItemService.java
+++ b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/ItemService.java
@@ -27,6 +27,8 @@
 import com.ctrip.framework.apollo.common.utils.BeanUtils;
 import com.ctrip.framework.apollo.core.utils.StringUtils;
 import org.springframework.context.annotation.Lazy;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -138,6 +140,10 @@ public List<Item> findItemsModifiedAfterDate(long namespaceId, Date date) {
     return itemRepository.findByNamespaceIdAndDataChangeLastModifiedTimeGreaterThan(namespaceId, date);
   }
 
+  public Page<Item> findItemsByKey(String key, Pageable pageable) {
+    return itemRepository.findByKey(key, pageable);
+  }
+
   @Transactional
   public Item save(Item entity) {
     checkItemKeyLength(entity.getKey());
diff --git a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/NamespaceService.java b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/NamespaceService.java
index ba1f8e1f685..54e5d805799 100644
--- a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/NamespaceService.java
+++ b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/NamespaceService.java
@@ -35,6 +35,8 @@
 import com.google.common.collect.Maps;
 import com.google.gson.Gson;
 import org.springframework.context.annotation.Lazy;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageImpl;
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -104,6 +106,21 @@ public Namespace findOne(String appId, String clusterName, String namespaceName)
                                                                          namespaceName);
   }
 
+  /**
+   * the returned content's size is not fixed. so please carefully used.
+   */
+  public Page<Namespace> findByItem(String itemKey, Pageable pageable) {
+    Page<Item> items = itemService.findItemsByKey(itemKey, pageable);
+
+    if (!items.hasContent()) {
+      return Page.empty();
+    }
+
+    Set<Long> namespaceIds = BeanUtils.toPropertySet("namespaceId", items.getContent());
+
+    return new PageImpl<>(namespaceRepository.findByIdIn(namespaceIds));
+  }
+
   public Namespace findPublicNamespaceForAssociatedNamespace(String clusterName, String namespaceName) {
     AppNamespace appNamespace = appNamespaceService.findPublicNamespaceByName(namespaceName);
     if (appNamespace == null) {
diff --git a/apollo-core/src/test/java/com/ctrip/framework/apollo/core/utils/StringUtilsTest.java b/apollo-core/src/test/java/com/ctrip/framework/apollo/core/utils/StringUtilsTest.java
index 9f366d6dc3b..5bcd7748c56 100644
--- a/apollo-core/src/test/java/com/ctrip/framework/apollo/core/utils/StringUtilsTest.java
+++ b/apollo-core/src/test/java/com/ctrip/framework/apollo/core/utils/StringUtilsTest.java
@@ -16,7 +16,6 @@
  */
 package com.ctrip.framework.apollo.core.utils;
 
-import com.ctrip.framework.apollo.core.utils.StringUtils;
 import org.junit.Assert;
 import org.junit.Test;
 
diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/api/AdminServiceAPI.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/api/AdminServiceAPI.java
index b149501dba0..3409162a333 100644
--- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/api/AdminServiceAPI.java
+++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/api/AdminServiceAPI.java
@@ -68,6 +68,10 @@ public void deleteApp(Env env, String appId, String operator) {
   @Service
   public static class NamespaceAPI extends API {
 
+    private ParameterizedTypeReference<PageDTO<NamespaceDTO>>
+        namespacePageDTO = new ParameterizedTypeReference<PageDTO<NamespaceDTO>>() {
+    };
+
     private ParameterizedTypeReference<Map<String, Boolean>>
         typeReference = new ParameterizedTypeReference<Map<String, Boolean>>() {
     };
@@ -79,6 +83,14 @@ public List<NamespaceDTO> findNamespaceByCluster(String appId, Env env, String c
       return Arrays.asList(namespaceDTOs);
     }
 
+    public PageDTO<NamespaceDTO> findByItem(Env env, String itemKey, int page, int size) {
+      ResponseEntity<PageDTO<NamespaceDTO>>
+          entity =
+          restTemplate.get(env, "/namespaces/find-by-item?itemKey={itemKey}&page={page}&size={size}",
+                           namespacePageDTO, itemKey, page, size);
+      return entity.getBody();
+    }
+
     public NamespaceDTO loadNamespace(String appId, Env env, String clusterName,
         String namespaceName) {
       return
diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/component/config/PortalConfig.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/component/config/PortalConfig.java
index 251c001fed1..c1162892565 100644
--- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/component/config/PortalConfig.java
+++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/component/config/PortalConfig.java
@@ -270,4 +270,7 @@ public String[] webHookUrls() {
     return getArrayProperty("config.release.webhook.service.url", null);
   }
 
+  public boolean supportSearchByItem() {
+    return getBooleanProperty("searchByItem.switch", true);
+  }
 }
diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AppController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AppController.java
index 09b4cf67030..421a78491f3 100644
--- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AppController.java
+++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/AppController.java
@@ -18,7 +18,6 @@
 
 
 import com.ctrip.framework.apollo.common.dto.AppDTO;
-import com.ctrip.framework.apollo.common.dto.PageDTO;
 import com.ctrip.framework.apollo.common.entity.App;
 import com.ctrip.framework.apollo.common.exception.BadRequestException;
 import com.ctrip.framework.apollo.common.http.MultiResponseEntity;
@@ -103,15 +102,6 @@ public List<App> findApps(@RequestParam(value = "appIds", required = false) Stri
     return appService.findByAppIds(Sets.newHashSet(appIds.split(",")));
   }
 
-  @GetMapping("/search/by-appid-or-name")
-  public PageDTO<App> searchByAppIdOrAppName(@RequestParam(value = "query", required = false) String query,
-      Pageable pageable) {
-    if (Strings.isNullOrEmpty(query)) {
-      return appService.findAll(pageable);
-    }
-    return appService.searchByAppIdOrAppName(query, pageable);
-  }
-
   @GetMapping("/by-owner")
   public List<App> findAppsByOwner(@RequestParam("owner") String owner, Pageable page) {
     Set<String> appIds = Sets.newHashSet();
@@ -184,7 +174,7 @@ public MultiResponseEntity<EnvClusterInfo> nav(@PathVariable String appId) {
   public ResponseEntity<Void> create(@PathVariable String env, @Valid @RequestBody App app) {
     appService.createAppInRemote(Env.valueOf(env), app);
 
-    roleInitializationService.initNamespaceSpecificEnvRoles(app.getAppId(), ConfigConsts.NAMESPACE_APPLICATION, 
+    roleInitializationService.initNamespaceSpecificEnvRoles(app.getAppId(), ConfigConsts.NAMESPACE_APPLICATION,
             env, userInfoHolder.getUser().getUserId());
 
     return ResponseEntity.ok().build();
diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/SearchController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/SearchController.java
new file mode 100644
index 00000000000..6d216cb7d30
--- /dev/null
+++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/SearchController.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2021 Apollo Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package com.ctrip.framework.apollo.portal.controller;
+
+import com.google.common.collect.Lists;
+
+import com.ctrip.framework.apollo.common.dto.NamespaceDTO;
+import com.ctrip.framework.apollo.common.dto.PageDTO;
+import com.ctrip.framework.apollo.common.entity.App;
+import com.ctrip.framework.apollo.portal.component.PortalSettings;
+import com.ctrip.framework.apollo.portal.component.config.PortalConfig;
+import com.ctrip.framework.apollo.portal.environment.Env;
+import com.ctrip.framework.apollo.portal.service.AppService;
+import com.ctrip.framework.apollo.portal.service.NamespaceService;
+
+import org.springframework.data.domain.Pageable;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * @author lepdou 2021-09-13
+ */
+@RestController("/app")
+public class SearchController {
+
+  private AppService       appService;
+  private PortalSettings   portalSettings;
+  private NamespaceService namespaceService;
+  private PortalConfig     portalConfig;
+
+  public SearchController(final AppService appService,
+                          final PortalSettings portalSettings,
+                          final PortalConfig portalConfig,
+                          final NamespaceService namespaceService) {
+    this.appService = appService;
+    this.portalConfig = portalConfig;
+    this.portalSettings = portalSettings;
+    this.namespaceService = namespaceService;
+  }
+
+  @GetMapping("/apps/search/by-appid-or-name")
+  public PageDTO<App> search(@RequestParam(value = "query", required = false) String query, Pageable pageable) {
+    if (StringUtils.isEmpty(query)) {
+      return appService.findAll(pageable);
+    }
+
+    //search app
+    PageDTO<App> appPageDTO = appService.searchByAppIdOrAppName(query, pageable);
+    if (appPageDTO.hasContent()) {
+      return appPageDTO;
+    }
+
+    if (!portalConfig.supportSearchByItem()) {
+      return new PageDTO<>(Lists.newLinkedList(), pageable, 0);
+    }
+
+    //search item
+    return searchByItem(query, pageable);
+  }
+
+  private PageDTO<App> searchByItem(String itemKey, Pageable pageable) {
+    List<App> result = Lists.newLinkedList();
+
+    if (StringUtils.isEmpty(itemKey)) {
+      return new PageDTO<>(result, pageable, 0);
+    }
+
+    //use the env witch has the most namespace as page index.
+    final AtomicLong maxTotal = new AtomicLong(0);
+
+    List<Env> activeEnvs = portalSettings.getActiveEnvs();
+
+    activeEnvs.forEach(env -> {
+      PageDTO<NamespaceDTO> namespacePage = namespaceService.findNamespacesByItem(env, itemKey, pageable);
+      if (!namespacePage.hasContent()) {
+        return;
+      }
+
+      long currentEnvNSTotal = namespacePage.getTotal();
+      if (currentEnvNSTotal > maxTotal.get()) {
+        maxTotal.set(namespacePage.getTotal());
+      }
+
+      List<NamespaceDTO> namespaceDTOS = namespacePage.getContent();
+
+      namespaceDTOS.forEach(namespaceDTO -> {
+        String cluster = namespaceDTO.getClusterName();
+        String namespaceName = namespaceDTO.getNamespaceName();
+
+        App app = new App();
+        app.setAppId(namespaceDTO.getAppId());
+        app.setName(env.getName() + " / " + cluster + " / " + namespaceName);
+        app.setOrgId(env.getName() + "+" + cluster + "+" + namespaceName);
+        app.setOrgName("SearchByItem" + "+" + itemKey);
+
+        result.add(app);
+      });
+    });
+
+    return new PageDTO<>(result, pageable, maxTotal.get());
+  }
+
+}
diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/AppService.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/AppService.java
index 34632a28184..ae6bb8eea9d 100644
--- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/AppService.java
+++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/AppService.java
@@ -36,7 +36,6 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 
diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/NamespaceService.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/NamespaceService.java
index eb227651d3e..bf6616265bb 100644
--- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/NamespaceService.java
+++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/NamespaceService.java
@@ -19,6 +19,7 @@
 import com.ctrip.framework.apollo.common.constants.GsonType;
 import com.ctrip.framework.apollo.common.dto.ItemDTO;
 import com.ctrip.framework.apollo.common.dto.NamespaceDTO;
+import com.ctrip.framework.apollo.common.dto.PageDTO;
 import com.ctrip.framework.apollo.common.dto.ReleaseDTO;
 import com.ctrip.framework.apollo.common.entity.AppNamespace;
 import com.ctrip.framework.apollo.common.exception.BadRequestException;
@@ -48,6 +49,7 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.context.annotation.Lazy;
+import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -181,6 +183,13 @@ public List<NamespaceDTO> findNamespaces(String appId, Env env, String clusterNa
     return namespaceAPI.findNamespaceByCluster(appId, env, clusterName);
   }
 
+  /**
+   * the returned content's size is not fixed. so please carefully used.
+   */
+  public PageDTO<NamespaceDTO> findNamespacesByItem(Env env, String itemKey, Pageable pageable) {
+    return namespaceAPI.findByItem(env, itemKey, pageable.getPageNumber(), pageable.getPageSize());
+  }
+
   public List<NamespaceDTO> getPublicAppNamespaceAllNamespaces(Env env, String publicNamespaceName,
       int page,
       int size) {
diff --git a/apollo-portal/src/main/resources/static/i18n/en.json b/apollo-portal/src/main/resources/static/i18n/en.json
index 08dafbbf805..f3b9ea60aaf 100644
--- a/apollo-portal/src/main/resources/static/i18n/en.json
+++ b/apollo-portal/src/main/resources/static/i18n/en.json
@@ -729,7 +729,7 @@
   "Valdr.Release.ReleaseName.Required": "Release Name cannot be empty",
   "Valdr.Release.Comment.Size": "Comment length should not exceed 256 characters",
   "ApolloConfirmDialog.DefaultConfirmBtnName": "OK",
-  "ApolloConfirmDialog.SearchPlaceHolder": "Search items (App Id, App Name)",
+  "ApolloConfirmDialog.SearchPlaceHolder": "Search Apps by appId, appName, configuration key",
   "RulesModal.ChooseInstances": "Select from the list of instances",
   "RulesModal.InvalidIp": "Illegal IP Address: '{{ip}}'",
   "RulesModal.GrayscaleAppIdCanNotBeNull": "Grayscale AppId cannot be empty",
@@ -764,4 +764,4 @@
   "Rollback.RollbackFailed": "Failed to Rollback",
   "Revoke.RevokeFailed": "Failed to Revoke",
   "Revoke.RevokeSuccessfully": "Revoke Successfully"
-}
\ No newline at end of file
+}
diff --git a/apollo-portal/src/main/resources/static/i18n/zh-CN.json b/apollo-portal/src/main/resources/static/i18n/zh-CN.json
index a284b6d036a..9fdb8573737 100644
--- a/apollo-portal/src/main/resources/static/i18n/zh-CN.json
+++ b/apollo-portal/src/main/resources/static/i18n/zh-CN.json
@@ -729,7 +729,7 @@
   "Valdr.Release.ReleaseName.Required": "Release Name不能为空",
   "Valdr.Release.Comment.Size": "备注长度不能多于256个字符",
   "ApolloConfirmDialog.DefaultConfirmBtnName": "确认",
-  "ApolloConfirmDialog.SearchPlaceHolder": "搜索应用(AppId、应用名)",
+  "ApolloConfirmDialog.SearchPlaceHolder": "搜索应用Id、应用名、配置项Key",
   "RulesModal.ChooseInstances": "从实例列表中选择",
   "RulesModal.InvalidIp": "不合法的IP地址: '{{ip}}'",
   "RulesModal.GrayscaleAppIdCanNotBeNull": "灰度的AppId不能为空",
diff --git a/apollo-portal/src/main/resources/static/scripts/controller/config/ConfigBaseInfoController.js b/apollo-portal/src/main/resources/static/scripts/controller/config/ConfigBaseInfoController.js
index a5008d92737..213a480ffd2 100644
--- a/apollo-portal/src/main/resources/static/scripts/controller/config/ConfigBaseInfoController.js
+++ b/apollo-portal/src/main/resources/static/scripts/controller/config/ConfigBaseInfoController.js
@@ -45,7 +45,9 @@ function ConfigBaseInfoController($rootScope, $scope, $window, $location, $trans
         $rootScope.pageContext = {
             appId: appId,
             env: urlParams.env ? urlParams.env : (scene ? scene.env : ''),
-            clusterName: urlParams.cluster ? urlParams.cluster : (scene ? scene.cluster : 'default')
+            clusterName: urlParams.cluster ? urlParams.cluster : (scene ? scene.cluster : 'default'),
+            namespaceName: urlParams.namespace,
+            item: urlParams.item,
         };
 
         //storage page context to session storage
@@ -201,7 +203,7 @@ function ConfigBaseInfoController($rootScope, $scope, $window, $location, $trans
                 $rootScope.pageContext.env = nodes[0].env;
             }
 
-            EventManager.emit(EventManager.EventType.REFRESH_NAMESPACE);
+            EventManager.emit(EventManager.EventType.REFRESH_NAMESPACE, {firstLoad: true});
 
             nodes.forEach(function (env) {
                 if (!env.clusters || env.clusters.length == 0) {
diff --git a/apollo-portal/src/main/resources/static/scripts/controller/config/ConfigNamespaceController.js b/apollo-portal/src/main/resources/static/scripts/controller/config/ConfigNamespaceController.js
index 99825eb1b25..06c6f0f9c82 100644
--- a/apollo-portal/src/main/resources/static/scripts/controller/config/ConfigNamespaceController.js
+++ b/apollo-portal/src/main/resources/static/scripts/controller/config/ConfigNamespaceController.js
@@ -107,12 +107,12 @@ function controller($rootScope, $scope, $translate, toastr, AppUtil, EventManage
             if (context.namespace) {
                 refreshSingleNamespace(context.namespace);
             } else {
-                refreshAllNamespaces();
+                refreshAllNamespaces(context);
             }
 
         });
 
-    function refreshAllNamespaces() {
+    function refreshAllNamespaces(context) {
         if ($rootScope.pageContext.env == '') {
             return;
         }
@@ -126,6 +126,19 @@ function controller($rootScope, $scope, $translate, toastr, AppUtil, EventManage
                     $('.config-item-container').removeClass('hide');
 
                     initPublishInfo();
+                    //If there is a namespace parameter in the URL, expand the corresponding namespace directly
+                    if (context && context.firstLoad && $rootScope.pageContext.namespaceName) {
+                        refreshSingleNamespace({
+                            baseInfo: {
+                                namespaceName: $rootScope.pageContext.namespaceName
+                            },
+                            searchInfo: {
+                                showSearchInput: true,
+                                searchItemKey: $rootScope.pageContext.item,
+                            }
+
+                        });
+                    }
                 }, function (result) {
                     toastr.error(AppUtil.errorMsg(result), $translate.instant('Config.LoadingAllNamespaceError'));
                 });
@@ -136,6 +149,9 @@ function controller($rootScope, $scope, $translate, toastr, AppUtil, EventManage
             return;
         }
 
+        const showSearchItemInput = namespace.searchInfo ? namespace.searchInfo.showSearchInput : false;
+        const searchItemKey = namespace.searchInfo ? namespace.searchInfo.searchItemKey : '';
+
         ConfigService.load_namespace($rootScope.pageContext.appId,
             $rootScope.pageContext.env,
             $rootScope.pageContext.clusterName,
@@ -143,11 +159,13 @@ function controller($rootScope, $scope, $translate, toastr, AppUtil, EventManage
                 function (result) {
 
                     $scope.namespaces.forEach(function (namespace, index) {
-                        if (namespace.baseInfo.namespaceName == result.baseInfo.namespaceName) {
+                        if (namespace.baseInfo.namespaceName === result.baseInfo.namespaceName) {
                             result.showNamespaceBody = true;
                             result.initialized = true;
                             result.show = namespace.show;
                             $scope.namespaces[index] = result;
+                            result.showSearchItemInput = showSearchItemInput;
+                            result.searchItemKey = searchItemKey;
                         }
                     });
 
diff --git a/apollo-portal/src/main/resources/static/scripts/directive/directive.js b/apollo-portal/src/main/resources/static/scripts/directive/directive.js
index f95e68bebe6..48dee6c94bd 100644
--- a/apollo-portal/src/main/resources/static/scripts/directive/directive.js
+++ b/apollo-portal/src/main/resources/static/scripts/directive/directive.js
@@ -56,7 +56,9 @@ directive_module.directive('apollonav',
                                     data.content.forEach(function (app) {
                                         result.push({
                                             id: app.appId,
-                                            text: app.appId + ' / ' + app.name
+                                            text: app.appId + ' / ' + app.name,
+                                            orgId: app.orgId,
+                                            orgName: app.orgName
                                         })
                                     });
                                     return {
@@ -81,17 +83,40 @@ directive_module.directive('apollonav',
                     $('#app-search-list').on('select2:select', function () {
                         var selected = $('#app-search-list').select2('data');
                         if (selected && selected.length) {
-                            jumpToConfigPage(selected[0].id)
+                            jumpToConfigPage(selected[0].id, selected[0].name, selected[0].orgName, selected[0].orgId)
                         }
                     });
                 });
 
-                function jumpToConfigPage(selectedAppId) {
+                function jumpToConfigPage(selectedAppId, name, type, namespaceInfo) {
                     if ($window.location.href.indexOf("config.html") > -1) {
-                        $window.location.hash = "appid=" + selectedAppId;
+                        if (type && type.startsWith('SearchByItem')) {
+                            var namespaceInfos = namespaceInfo.split('+');
+                            var env = namespaceInfos[0];
+                            var cluster = namespaceInfos[1];
+                            var namespaceName = namespaceInfos[2];
+                            var searchKey = type.split("+")[1];
+                            $window.location.hash =
+                                "appid=" + selectedAppId + "&env=" + env + "&cluster=" + cluster + "&namespace="
+                                + namespaceName + "&item=" + searchKey;
+                        } else {
+                            $window.location.hash = "appid=" + selectedAppId;
+                        }
+
                         $window.location.reload();
                     } else {
-                        $window.location.href = AppUtil.prefixPath() + '/config.html?#appid=' + selectedAppId;
+                        if (type && type.startsWith('SearchByItem')) {
+                            var namespaceInfos = namespaceInfo.split('+');
+                            var env = namespaceInfos[0];
+                            var cluster = namespaceInfos[1];
+                            var namespaceName = namespaceInfos[2];
+                            var searchKey = type.split("+")[1];
+                            $window.location.href =
+                                AppUtil.prefixPath() + '/config.html?#appid=' + selectedAppId + "&env=" + env
+                                + "&cluster=" + cluster + "&namespace=" + namespaceName + "&item=" + searchKey;
+                        } else {
+                            $window.location.href =  AppUtil.prefixPath() + '/config.html?#appid=' + selectedAppId;
+                        }
                     }
                 };
 
diff --git a/apollo-portal/src/main/resources/static/scripts/directive/namespace-panel-directive.js b/apollo-portal/src/main/resources/static/scripts/directive/namespace-panel-directive.js
index 59935e8a777..47d4f632809 100644
--- a/apollo-portal/src/main/resources/static/scripts/directive/namespace-panel-directive.js
+++ b/apollo-portal/src/main/resources/static/scripts/directive/namespace-panel-directive.js
@@ -66,6 +66,7 @@ function directive($window, $translate, toastr, AppUtil, EventManager, Permissio
             scope.toggleItemSearchInput = toggleItemSearchInput;
             scope.toggleHistorySearchInput = toggleHistorySearchInput;
             scope.searchItems = searchItems;
+            scope.resetSearchItems = resetSearchItems;
             scope.searchHistory = searchHistory;
             scope.loadCommitHistory = loadCommitHistory;
             scope.toggleTextEditStatus = toggleTextEditStatus;
@@ -130,7 +131,8 @@ function directive($window, $translate, toastr, AppUtil, EventManager, Permissio
                 namespace.isBranch = false;
                 namespace.displayControl = {
                     currentOperateBranch: 'master',
-                    showSearchInput: false,
+                    showSearchInput: namespace.showSearchItemInput,
+                    searchItemKey: namespace.searchItemKey,
                     showHistorySearchInput: false,
                     show: scope.showBody
                 };
@@ -153,6 +155,7 @@ function directive($window, $translate, toastr, AppUtil, EventManager, Permissio
                 initPermission(namespace);
                 initLinkedNamespace(namespace);
                 loadInstanceInfo(namespace);
+                initSearchItemInput(namespace);
 
                 function initNamespaceBranch(namespace) {
                     NamespaceBranchService.findNamespaceBranch(scope.appId, scope.env,
@@ -398,6 +401,12 @@ function directive($window, $translate, toastr, AppUtil, EventManager, Permissio
 
                 }
 
+                function initSearchItemInput(namespace) {
+                    if (namespace.displayControl.searchItemKey) {
+                        namespace.searchKey = namespace.displayControl.searchItemKey;
+                        searchItems(namespace);
+                    }
+                }
             }
 
             function initNamespaceInstancesCount(namespace) {
@@ -863,6 +872,11 @@ function directive($window, $translate, toastr, AppUtil, EventManager, Permissio
                 namespace.viewItems = items;
             }
 
+            function resetSearchItems(namespace) {
+                namespace.searchKey = '';
+                searchItems(namespace);
+            }
+
             function toggleHistorySearchInput(namespace) {
                 namespace.displayControl.showHistorySearchInput = !namespace.displayControl.showHistorySearchInput;
             }
diff --git a/apollo-portal/src/main/resources/static/styles/common-style.css b/apollo-portal/src/main/resources/static/styles/common-style.css
index f7b20df41aa..99161f733af 100644
--- a/apollo-portal/src/main/resources/static/styles/common-style.css
+++ b/apollo-portal/src/main/resources/static/styles/common-style.css
@@ -451,7 +451,7 @@ table th {
 }
 
 .namespace-panel .namespace-view-table .search-input input {
-    width: 350px;
+    width: 500px;
 }
 
 .namespace-panel .no-config-panel {
@@ -836,4 +836,4 @@ table th {
 .app-search-list .select2-container .select2-selection .select2-selection__rendered {
     line-height: 34px;
     font-size: 14px;
-}
\ No newline at end of file
+}
diff --git a/apollo-portal/src/main/resources/static/views/component/namespace-panel-master-tab.html b/apollo-portal/src/main/resources/static/views/component/namespace-panel-master-tab.html
index 5d374db50c3..08424c8d4b1 100644
--- a/apollo-portal/src/main/resources/static/views/component/namespace-panel-master-tab.html
+++ b/apollo-portal/src/main/resources/static/views/component/namespace-panel-master-tab.html
@@ -253,9 +253,14 @@
                 <!--not link namespace-->
                 <div ng-if="!namespace.isLinkedNamespace">
                     <div class="search-input" ng-show="namespace.displayControl.showSearchInput">
-                        <input type="text" class="form-control"
-                            placeholder="{{'Component.Namespace.Master.Items.Body.FilterByKey' | translate }}"
-                            ng-model="namespace.searchKey" ng-change="searchItems(namespace)">
+                        <form class="form-inline">
+                            <div class="form-group">
+                                <input type="text" class="form-control" id="searchItemKeyInput"
+                                       placeholder="{{'Component.Namespace.Master.Items.Body.FilterByKey' | translate }}"
+                                       ng-model="namespace.searchKey" ng-change="searchItems(namespace)">
+                            </div>
+                            <button type="button" class="btn btn-default" ng-click="resetSearchItems(namespace)">{{'Config.Sync.Rest' | translate }}</button>
+                        </form>
                     </div>
 
                     <table class="table table-bordered table-striped table-hover">
@@ -1140,4 +1145,4 @@ <h5>{{'Component.Namespace.Master.Items.Body.NoPublished.Title' | translate }}</
         </section>
     </div>
 
-</section>
\ No newline at end of file
+</section>
diff --git a/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/controller/SearchControllerTest.java b/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/controller/SearchControllerTest.java
new file mode 100644
index 00000000000..77b4a181e21
--- /dev/null
+++ b/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/controller/SearchControllerTest.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2021 Apollo Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package com.ctrip.framework.apollo.portal.controller;
+
+import com.google.common.collect.Lists;
+
+import com.ctrip.framework.apollo.common.dto.NamespaceDTO;
+import com.ctrip.framework.apollo.common.dto.PageDTO;
+import com.ctrip.framework.apollo.common.entity.App;
+import com.ctrip.framework.apollo.portal.component.PortalSettings;
+import com.ctrip.framework.apollo.portal.component.config.PortalConfig;
+import com.ctrip.framework.apollo.portal.environment.Env;
+import com.ctrip.framework.apollo.portal.service.AppService;
+import com.ctrip.framework.apollo.portal.service.NamespaceService;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.springframework.data.domain.PageImpl;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+
+import java.util.List;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+
+/**
+ * @author lepdou 2021-09-13
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class SearchControllerTest {
+
+  @Mock
+  private AppService       appService;
+  @Mock
+  private NamespaceService namespaceService;
+  @Mock
+  private PortalSettings   portalSettings;
+  @Mock
+  private PortalConfig     portalConfig;
+  @InjectMocks
+  private SearchController searchController;
+
+  @Test
+  public void testSearchByEmptyKey() {
+    PageRequest request = PageRequest.of(0, 20);
+    searchController.search("", request);
+    verify(appService, times(1)).findAll(request);
+  }
+
+  @Test
+  public void testSearchApp() {
+    String query = "timeout";
+    PageRequest request = PageRequest.of(0, 20);
+
+    PageDTO<App> apps = genPageApp(10, request, 100);
+
+    when(appService.searchByAppIdOrAppName(query, request)).thenReturn(apps);
+
+    searchController.search(query, request);
+
+    verify(appService, times(0)).findAll(request);
+    verify(appService, times(1)).searchByAppIdOrAppName(query, request);
+  }
+
+  @Test
+  public void testSearchItemSwitch() {
+    String query = "timeout";
+    PageRequest request = PageRequest.of(0, 20);
+
+    PageDTO<App> apps = new PageDTO<>(Lists.newLinkedList(), request, 0);
+
+    when(appService.searchByAppIdOrAppName(query, request)).thenReturn(apps);
+    when(portalConfig.supportSearchByItem()).thenReturn(false);
+
+    PageDTO<App> result = searchController.search(query, request);
+
+    Assert.assertFalse(result.hasContent());
+    verify(appService, times(0)).findAll(request);
+    verify(appService, times(1)).searchByAppIdOrAppName(query, request);
+  }
+
+  @Test
+  public void testSearchItem() {
+    String query = "timeout";
+    PageRequest request = PageRequest.of(0, 20);
+
+    PageDTO<App> apps = new PageDTO<>(Lists.newLinkedList(), request, 0);
+    PageDTO<NamespaceDTO> devNamespaces = genPageNamespace(10, request, 20);
+    PageDTO<NamespaceDTO> fatNamespaces = genPageNamespace(15, request, 30);
+
+    when(appService.searchByAppIdOrAppName(query, request)).thenReturn(apps);
+    when(portalConfig.supportSearchByItem()).thenReturn(true);
+    when(portalSettings.getActiveEnvs()).thenReturn(Lists.newArrayList(Env.DEV, Env.FAT));
+    when(namespaceService.findNamespacesByItem(Env.DEV, query, request)).thenReturn(devNamespaces);
+    when(namespaceService.findNamespacesByItem(Env.FAT, query, request)).thenReturn(fatNamespaces);
+
+    PageDTO<App> result = searchController.search(query, request);
+
+    Assert.assertTrue(result.hasContent());
+    Assert.assertEquals(25, result.getContent().size());
+    Assert.assertEquals(30, result.getTotal());
+    verify(appService, times(0)).findAll(request);
+    verify(appService, times(1)).searchByAppIdOrAppName(query, request);
+    verify(namespaceService).findNamespacesByItem(Env.DEV, query, request);
+    verify(namespaceService).findNamespacesByItem(Env.FAT, query, request);
+  }
+
+  private PageDTO<App> genPageApp(int size, Pageable pageable, int total) {
+    List<App> result = Lists.newLinkedList();
+    for (int i = 0; i < size; i++) {
+      App app = new App();
+      result.add(app);
+    }
+    return new PageDTO<>(result, pageable, total);
+  }
+
+  private PageDTO<NamespaceDTO> genPageNamespace(int size, Pageable pageable, int total) {
+    List<NamespaceDTO> result = Lists.newLinkedList();
+    for (int i = 0; i < size; i++) {
+      NamespaceDTO namespaceDTO = new NamespaceDTO();
+      result.add(namespaceDTO);
+    }
+    return new PageDTO<>(result, pageable, total);
+  }
+}
diff --git a/docs/zh/deployment/distributed-deployment-guide.md b/docs/zh/deployment/distributed-deployment-guide.md
index e228b7b53f3..1c32f786cd3 100644
--- a/docs/zh/deployment/distributed-deployment-guide.md
+++ b/docs/zh/deployment/distributed-deployment-guide.md
@@ -1152,6 +1152,12 @@ portal上“帮助”链接的地址,默认是Apollo github的wiki首页,可
 
 ### 3.1.12 admin-service.access.tokens - 设置apollo-portal访问各环境apollo-adminservice所需的access token
 
+### 3.1.13 searchByItem.switch - 控制台搜索框是否支持按配置项搜索
+
+默认为 true,可以方便的按配置项快速搜索配置
+
+如果设置为 false,则关闭此功能 
+
 > 适用于1.7.1及以上版本
 
 如果对应环境的apollo-adminservice开启了[访问控制](#_326-admin-serviceaccesscontrolenabled-配置apollo-adminservice是否开启访问控制),那么需要在此配置apollo-portal访问该环境apollo-adminservice所需的access token,否则会访问失败
diff --git a/scripts/sql/delta/v190-v1_10_0/apolloconfigdb-v190-v1_10_0.sql b/scripts/sql/delta/v190-v1_10_0/apolloconfigdb-v190-v1_10_0.sql
new file mode 100644
index 00000000000..1d4fb655af1
--- /dev/null
+++ b/scripts/sql/delta/v190-v1_10_0/apolloconfigdb-v190-v1_10_0.sql
@@ -0,0 +1,20 @@
+--
+-- Copyright 2021 Apollo Authors
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+# delta schema to upgrade apollo config db from v1.9.0 to v1.10.0
+
+Use ApolloConfigDB;
+
+ALTER TABLE Item ADD INDEX IX_key (`Key`);