2015-07-22 7 views
6

Это будет очень здорово, если кто-нибудь предоставит мне небольшую помощь в mysql.Пересечение Mysql двух наборов, имеющих значение, разделенное запятой

У меня есть таблица с 1 миллиардом записей, в которой один столбец имеет значение, разделенное запятой.

У меня есть значения, разделенные запятой, чтобы выполнить поиск.

Я хочу выбрать те строки, которые имеют значение any в этом столбце, разделенном запятыми, от этого строкового значения.

например, таблицы А, имеющий столбец comma_separated как это: -

enter image description here

и у меня есть строка, имеющая значение, разделенная запятая "79, 62, 70, 107".

Результат будет номер строки 1,2,3,5,7,8,9,10 (В упоминании изображения.)

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

+0

Пожалуйста, покажите нам свои попытки. –

+0

Очень плохой дизайн базы данных! – Jens

+0

Еще одно решение, которое я так думаю, с сохраненной функцией (которая будет использовать цикл с функцией find_in_set), которая будет обеспечивать логическое значение для установки и использования этого запроса. Но не знаю, как это сделать. –

ответ

2

Вы не можете оптимизировать то, что делаете. В принципе, вы можете запускать такой запрос:

where find_in_set(79, comma_separated) > 0 or 
     find_in_set(62, comma_separated) > 0 or 
     find_in_set(70, comma_separated) > 0 or 
     find_in_set(107, comma_separated) > 0 

Для этого требуется сканирование полной таблицы. И хотя производительность может быть немного лучше, чем регулярное выражение, оно все равно будет неэффективным.

Правильный способ хранения этих данных - это таблица соединений. Это умножает количество строк, поэтому первая строка в ваших данных становится тремя строками в таблице соединений (по одному для каждого значения).

Существует множество причин, по которым вы не хотите хранить списки вещей как список, разделенный запятыми. Ваши ценности выглядят как идентификаторы в другой таблице, что еще хуже:

  • Значения должны храниться в собственном формате. Таким образом, сохранение целых чисел в виде строк является плохой идеей.
  • Собственная структура списков в SQL - это таблица, а не список.
  • Функции на таблицах более мощные и строковые.
  • SQL не может использовать индексы (за исключением полных текстовых индексов) для операций со строками.
  • Если у вас есть идентификатор, относящийся к другой таблице, у вас должно быть ограничение внешнего ключа. Вы не можете сделать это со списками, хранящимися в строке.
0

Если вы заинтересованы в производительности, вам следует рассмотреть возможность изменения структуры вашей БД. Числа не индексируются хорошо (если вообще) в текстовых типах столбцов.

Похоже, что у вас есть постоянное число целых чисел в столбце "comma_separated".

Рассмотрите возможность создания отдельного столбца типа INT для каждого из трех, т.е.:

num1 | num2 | num3 
79 | 62 | 101 
101 | 5 | 70 

Тогда вы могли бы сделать правильный выбор, как:

WHERE 
    num1 IN (79, 62, 70, 107) 
    OR num2 IN (79, 62, 70, 107) 
    OR num3 IN (79, 62, 70, 107) 
Смежные вопросы