索引设计
- 字段类型选择:使用最紧凑的数据类型,例如能用
keyword
就不用 text
,text
类型会进行分词,占用更多空间和资源。如存储邮政编码,使用 keyword
类型。
- 索引分片:根据数据量和集群规模合理设置分片数。例如数据量极大且集群节点多,适当增加分片数,但不宜过多,过多会增加管理开销。初始可按经验公式
分片数 = 节点数 * 3
来设置,后续根据实际情况调整。
- 映射优化:避免过度嵌套,嵌套文档虽然能模拟对象结构,但查询时性能损耗大。如能用扁平化结构表示数据,优先使用扁平化。
节点配置
- 硬件资源:为节点分配足够的内存、CPU 和磁盘 I/O 资源。内存方面,Elasticsearch 堆内存建议不超过 32GB,防止内存溢出。磁盘使用 SSD,提升读写速度。
- 节点角色:明确划分不同角色的节点,如
master
节点负责集群管理,配置较低的 CPU 和内存;data
节点负责数据存储和读写,分配较多资源;coordinating
节点负责请求分发,根据请求量调整资源。
查询语句优化
- 使用过滤:将查询条件中不参与打分的部分放到
filter
子句中,filter
不会计算相关性分数,执行速度快。例如查询价格大于 100 且品牌为“Apple”的产品:
{
"query": {
"bool": {
"filter": [
{ "range": { "price": { "gt": 100 } } },
{ "term": { "brand": "Apple" } }
]
}
}
}
- 避免通配符查询:通配符查询性能较差,尽量使用
term
或 terms
查询替代。若必须使用,将通配符置于词尾,如 {"wildcard": {"field": "value*"}}
比 {"wildcard": {"field": "*value"}}
性能好。
- 批量查询:使用
mget
或 bulk
API 进行批量操作,减少网络开销。如查询多个文档:
{
"docs": [
{ "_index": "index1", "_id": "1" },
{ "_index": "index1", "_id": "2" }
]
}
复杂多条件联合查询优化思路及操作
- 分析查询条件:区分过滤条件和排序、打分条件。例如查询销量高且好评率大于 90% 的商品,销量高用于排序,好评率大于 90% 用于过滤。
- 构建布尔查询:利用
bool
查询将不同条件组合。must
子句用于必须满足的条件,should
子句用于选择性条件,filter
子句用于过滤不打分条件。如:
{
"query": {
"bool": {
"must": [
{ "term": { "category": "electronics" } }
],
"filter": [
{ "range": { "rating": { "gte": 4 } } }
],
"should": [
{ "term": { "featured": true } }
],
"sort": [
{ "sales": { "order": "desc" } }
]
}
}
}
- 缓存查询结果:对于频繁查询且数据变动不大的结果,使用缓存技术,如 Redis。先查询缓存,若缓存中有结果则直接返回,减少 Elasticsearch 的查询压力。