2013-06-20 5 views
1

У меня есть большие таблицы, содержащие МИЛЛИОНЫ данных (слишком слишком огромные).Принимая очень эффективное соединение между двумя таблицами в Oracle

Таблицы являются

Post 
post_id,user_id,description,creation_date, xyz, abc ,etc 

primarykey for post :post_id 
partition key for Post : creation_date 
index on Post : user_id 

Comment: 
commentid,post_id, comment_creation_date,comment_type,last_modified_date 

Primary key of comment = commentid 
indexed colums on Comment = commentid, postid 
partition key for Comment table = comment_creation_date 

Примечание: Я не могу создать новый индекс не изменяет схему таблицы в любом случае

комментарий типа имеет строки

Теперь данный список comment_type и а comment_creation_date диапазон Мне нужно найти все сообщения, у которых есть такой тип comment_type.

Простой и очень неэффективное решение будет

select * from post p, comment c where c.post_id = p.post_id where c.comment_creation_date > ? and c.comment_creation_date < ? 
and p.posttype IN (some list) 

Как я могу оптимизировать этот запрос? Что делать, если то же самое по last_modified_date комментария, а не comment_date. Примечание:

last_modified_date is NOT indexed and comment_date Is 

После того как запрос успешно я хочу, чтобы получить все комментарии одного поста вместе. Пример, если post1 с c1, c2, c3

PS: Я плохо разбираюсь в запросах. Я знаю, что IN не подходит для производительности.

+0

Если это не так быстро, я не уверен, что вы сможете получить гораздо быстрее, не меняя схему каким-либо образом. Схема - очень важная часть производительности. Вы можете попробовать _SELECT * FROM post WHERE EXISTS (SELECT NULL FROM comment WHERE ...) _, но я уверен, что перфоманс будет похож. – jods

ответ

0

Я не уверен, если это позволит сэкономить время, но, возможно, перемещая комментарий раздел подзапроса поможет:

SELECT * 
FROM Post p 
JOIN (SELECT * 
     FROM Comment 
     WHERE comment_creation_date > ? and comment_creation_date < ? 
       AND 'stringlist' LIKE '%'||comment_type||'%' 
    )c 
ON c.post_id = p.post_id 
0

Ваш запрос синтаксически неверен, так как он имеет два where положения. Кроме того, вы ссылаетесь на comment_type в код, но на post_type в коде. Я возьму последний. Вы можете записать его в виде:

select * 
from post p, comment c 
where c.post_id = p.post_id and 
     c.comment_creation_date > ? and c.comment_creation_date < ? and 
     p.posttype IN (some list) 

Oracle имеет хороший оптимизатор, так что нет никаких оснований полагать, что это будет оптимизировать плохо.

Хотя это не имеет никакого влияния на производительность, стандарт ANSI присоединиться синтаксис это лучший способ, чтобы написать запрос:

select * 
from post p join 
    comment c 
    on c.post_id = p.post_id 
where c.comment_creation_date > ? and c.comment_creation_date < ? and 
     p.posttype IN (some list) 

Оптимизировать может решить, когда делать какие фильтры и как сделать присоединиться. Вы можете сделать любую версию более эффективной, указав индекс на comment(comment_creation_date, post_id) и, возможно, на post(post_type) (последний зависит от того, сколько у вас разных типов сообщений, что называется избирательностью индекса).

Я не уверен, что вы подразумеваете под «Я знаю, что IN in not good for performance». Это не общеизвестно; пожалуйста, поделитесь ссылкой на эту ссылку. Насколько мне известно, in с кучей констант должен выполнять не хуже, чем куча выражений вроде p.posttype = <value1> or p.posttype = <value2> . . ..

Смежные вопросы