2015-06-21 3 views
0

У меня есть таблица SQL, подобная следующие:SQL - быстрый способ обновить столбец записи

id | text | other_columns... 
---------------------------- 
0 | a |  ... 
1 | b |  ... 
2 | c |  ... 

Мне нужно применить некоторые сложные операции со значениями в text столбце, а затем обновить поля с новые значения.

// Get all the current values. 
entries = SELECT id,text FROM foo_table; 

// Apply some complex operation to the text values (this part is Python, not SQL). 
foreach entry in entries 
    entry.text = f(entry.text) 

// Update the text fields (1 UPDATE per entry). 
foreach entry in entries 
    UPDATE foo_table SET text=entry.text WHERE id=entry.id; 

Это приводит к таблице, как это, с обновленными текстовых значений:

id | text | other_columns... 
---------------------------- 
0 | x |  ... 
1 | y |  ... 
2 | z |  ... 

Это занимает ~ 1 мс на UPDATE, и у меня есть ~ .5 млн записей, что приводит к ~ 8 минут выполнение. Я выполняю команды SQL (1000 за раз), но это все еще кажется очень медленным/неэффективным.

Есть ли лучший (более быстрый) способ сделать это? Благодарю.

+0

Что такое сложная операция (если вы можете нам сказать)? Возможно, это можно сделать в SQL, и это определенно ускорит его. –

+1

Может ли предоставить данные для создания stmt с показанными индексами – Drew

+0

@ PabloGonzálezAlba «Комплексная операция» выполняет кучу пользовательской строковой токенизации/подстановки и ссылки на внешние источники данных. К сожалению, это невозможно сделать в SQL (и даже если это можно было бы сделать, это нереально дорого для повторного внедрения в SQL). – smg

ответ

2

Экспортировать в txtfile с двумя столбцами через экспорт OUTFILE.

SELECT id, theText 
    INTO OUTFILE '/path/to/file.csv' 
    FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' 
    LINES TERMINATED BY '\n' 
    FROM myTable 

Have Py сделать из него.

Может иметь 2 колонки или 3. Скажем, 3 для целей отладки.

Теперь у вас есть выход. Вернитесь в mysql с INFILE в рабочую таблицу с id, newText.

LOAD DATA INFILE 'data.txt' INTO TABLE worktable 
    FIELDS TERMINATED BY ',' ENCLOSED BY '"' 
     LINES TERMINATED BY '\r\n'; 

https://dev.mysql.com/doc/refman/5.1/en/load-data.html

Обратите внимание, что данные для импорта могут иметь ROW1 с именами столбцов. Конечно, Row1 может быть пропущен для импорта данных, но, назвав столбцы, вы вводите только определенные столбцы. В вашем случае 2 из 3 столбцов.

Добавить индекс на worktable.id ПОСЛЕ импорта.

Обновление будет быстро.

UPDATE myTable 
JOIN worktable 
ON worktable.id=myTable.id 
SET myTable.text=worktable.newText 

Все это может произойти в прилагаемом сценарии bash. Если не знаете, как, пожалуйста, спросите.

+0

Да, вы могли бы иметь хранимую процедуру в SQL, которая принимает всю таблицу в качестве параметра, а затем обновляет таблицу целей таблицей хранимой процедуры. Это позволит вам вытащить всю таблицу в ваш код на Python, внести все изменения, а затем обновить все сразу. – DiscipleMichael

+0

@DiscipleMichael ему нужно получить код python – Drew

+0

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

1

я мог бы что-то отсутствует большая здесь, но почему вы не можете просто сделать

Update foo_table; 
Set foo_table.text = f(foo_table.text) 
+0

Cuz f is python – Drew

+0

Правильно, но если он действительно вызывает функцию f() в коде SQL, он тоже должен это сделать. Может быть, он просто упростил вызов функции ради краткости? – DiscipleMichael

+0

Я так не думаю. Он был исследован об этом – Drew

1

Вы можете использовать UDF, но вы должны переписать функцию в C.

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