Вы на самом деле не видите «повторяющиеся» строки в самом строгом смысле этого слова.
То, что вы видите, это декартово произведение , в котором каждая строка в одной таблице соединена с каждой отдельной строкой в другой таблице. Вы получаете это, потому что у вас есть декартово соединение (или перекрестное соединение, если вы предпочитаете) в вашем SQL-выражении:
SELECT * FROM events, eventStats
-- ^^^^^^^^^^^^^^^^^^
Это означает, что для каждой строки в таблице events
вы получите число результатов, равное количеству строк в таблице eventStats
. Добавьте все это вместе, и то, что выглядит как множество дубликатов, на самом деле представляет собой потенциально огромное количество уникальных комбинаций всех строк из обеих таблиц, объединенных в кучу.
Существует несколько сценариев, в которых желательно декартово объединение, однако оно очень часто является показателем ошибочного запроса и может оказать огромное влияние на производительность вашей системы, если одна из таблиц особенно велика. 1
Чтобы избежать этого, вам необходимо указать, какой столбец в каждой из ваших таблиц использовать для объединения двух таблиц, либо через явное соединение:
SELECT *
FROM events v
[INNER|LEFT OUTER|RIGHT OUTER] JOIN eventStats s
ON v.SomeColumn = s.SomeMatchingColumn
или неявный:
SELECT *
FROM events v, eventStats s
WHERE v.SomeColumn = s.SomeMatchingColumn
Трудно сказать вам больше, не видя структуру таблицы, но, вероятно, между этими двумя таблицами существует связь по внешнему ключу, и это столбец, к которому вы хотите присоединиться.
1 Количество строк, возвращаемых декартовым объединением, равно произведению размеров таблиц, участвующих в объединении. Например, скажем, таблица events
содержит 50 000 строк, а таблица eventStats
также содержит 50 000 строк, по одной на каждый event
. С декартовым объединением этих таблиц ваш запрос вернет огромные 2 500 000 000 , да, это 2,5 миллиардов строк данных. А теперь представьте, что вы читаете все это в ArrayList
... за исключением того, что вы не можете, потому что массивы Java не могут быть такими большими! Ваше приложение завершится с ошибкой java.lang.OutOfMemoryError: Requested array size exceeds VM limit
или java.lang.OutOfMemoryError: Java heap space
, прежде чем вы сможете прочитать все данные в.