我有一个包含 5 亿多行的大表。我试图找到最好的索引替代方法来稍微加快查询时间。我想根据时间戳排序会大大减慢查询时间。该表中有 15 列。
MyTable@ManyToOne与 other_table有关系。用户也可以定义最大结果。代码如下所示:
// Im showing the query itself here instead of the name of @NamedQuery inside the entity class.
TypedQuery<MyTable> query = em.createNamedQuery("SELECT m FROM my_table m WHERE m.other_table.id = :id AND m.city in :cities ORDER BY m.timestamp DESC", MyTable.class);
query.setParameter("id", id);
query.setParameter("cities", cities);
query.setMaxResults(number);
return query.getResultList();
Run Code Online (Sandbox Code Playgroud)
这种类型的查询的最佳替代方法是什么?综合指数?哪种索引类型最适合这种情况?
我们有一个这样的索引,但正如我所说,这需要很长时间。
CREATE INDEX my_table_idx ON my_schema.my_table USING btree (other_table_id, timestamp DESC NULLS LAST, city)
Run Code Online (Sandbox Code Playgroud)
编辑:
这是执行计划:
// Im showing the query itself here instead of …Run Code Online (Sandbox Code Playgroud) 我有一个名为"logTransaction"的集合.我想得到结果,你可以在附图中看到.
logTransaction有很多字段,但用于此图像的字段是:
customer,environment,firstTime,lastTime,integrationIds[](一个事务可以具有多于1个积分),transactionStatus(FINISHED,UNFINISHED,FAILED)
我正在使用AggregationOutput这个结果但它花了超过30秒,这比我拥有的数据量要长得多(我想).我只是想知道我是否可以通过修改我已经拥有的东西或者我应该完全改变它来改进它.我应该使用什么类型的索引来使事情更快?
我用MongoDB和Grails.我目前的方法如下:
def myCustomAggregation(integrations, timestamp_lt, timestamp_gt, cust, env) {
def currentRequest = RequestContextHolder.requestAttributes
def customer = cust ?: currentRequest?.session?.customer
def environment = env ?: currentRequest?.session?.environment
//$match
DBObject matchMap = new BasicDBObject('integrationIds', new BasicDBObject('$in', integrations.collectAll { it?.baselineId }))
matchMap.put("firstTimestamp", new BasicDBObject('$lte', timestamp_lt as Long).append('$gte', timestamp_gt as Long))
matchMap.put("customer",customer)
matchMap.put("environment",environment)
DBObject match = new BasicDBObject('$match',matchMap);
//$group1
Map<String, Object> dbObjIdMap1 = new HashMap<String, …Run Code Online (Sandbox Code Playgroud) 我有一个方法需要2个列表作为参数,你可以在方法体中看到我想做一些过滤并将结果返回给调用者.我想用lambda表达式将此代码转换为Java 8流,但我无法弄清楚.我最终为此创建了多个流,它击败了这个重构(恕我直言)的目的.我想知道的是,我如何以简单的方式将其重构为一个流?
public Set<CustomerTrack> getCustomerTracks(List<CusomerTrack> tracks, List<Customer> customers) {
Set<CustomerTrack> tracksToSave = new HashSet<>();
for (Customer customer : customers) {
if (customer.getTrack() == null) {
continue;
}
Long allowedTrackId = customer.getTrack().getId();
for (CustomerTrack track : tracks) {
if (Long.valueOf(track.getId()).equals(allowedTrackId)) {
tracksToSave.add(track);
}
}
}
return tracksToSave;
}
Run Code Online (Sandbox Code Playgroud) private Feature findFeature(String name, List<Feature> list) {
for (Feature item : list) {
if (item.getName().equals(name)) {
return item;
}
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
我还有 10 个类似的方法。相同的签名,相同的逻辑。唯一不同的是 List 参数使用不同的对象,例如List<Data> list、 或List<Option> list等。所有对象都有一个getName()方法。我想创建一个通用方法并删除所有其他方法。
如果我使用这样的东西,
private <T> T findInList(String name, List<T> list) {
Run Code Online (Sandbox Code Playgroud)
我无权访问该getName()方法。创建此方法的最简单方法是什么?反射 api 是唯一的选择吗?
编辑:
我发现了我犯的错误。它工作得很好,像这样:
for (FeatureEntity entity : data.getFeatures()) {
Predicate<Feature> filter = f -> f.getName().equalsIgnoreCase(entity.getName());
if (entity.getFeatureId() != null && findInList(featureList, filter) == null) {
FeatureEntity n = new FeatureEntity(); …Run Code Online (Sandbox Code Playgroud) java ×2
generics ×1
grails ×1
indexing ×1
java-8 ×1
java-stream ×1
mongodb ×1
named-query ×1
postgresql ×1
sql ×1