对拆分字段的查询


单值查询

select * from table1 
where user_id=‘test1234’


user_id 是分库时的拆分字段,只需要用分库时的路由算法对‘test1234’进行计算,找出这条记录是在哪个分库,然后直接去目标分库取得记录

例如

hash(test1234) = 2398283927 % 1024 = 531 -> 分库3

跨库的查询策略_java

多值查询

SELECT * FROM table1


WHERE user_id IN 
(‘test1234’,’papa17’,’abcd’)


分别对每个值进行路由计算,看是在哪个分库上,然后去不同分库中查找,最后汇合各分库的查询结果

例如

hash(test1234) = 2398283927 % 1024 = 531 -> 分库3
hash(papa17) = 3339829221 % 1024 = 511 -> 分库3
hash(abcd) = 55239822711 % 1024 = 130 -> 分库1




对非拆分字段的查询


SELECT * FROM table1


WHERE name = ‘dys’


name 字段不是拆分字段,这种情况就比较低效了,需要到各个分库中查询,最后汇合各分库的查询结果




join 连接查询


SELECT * 


FROM table1 INNER JOIN table2 


ON table1.user_id = table2.name

跨库的join操作没有什么非常高效的办法,需要各个分库迭代查询

跨库的查询策略_java_02

伪代码示例

for row in  (select * from table1)

{
add

(select * from table2 

where table2.name = row.user_id
)

to result
}


对于垮库的join,数据库中间件大多只能支持简单的连接操作,在实际应用中,因为性能的问题,很少会使用这种垮库join,例如京东,这类复杂查询是使用搜索服务(如 solr)来完成