Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / помогите выбрать самый быстрый вариант / 25 сообщений из 35, страница 1 из 2
19.09.2014, 16:05:36
    #38751723
Артем_sql
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
Есть таблица:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
CREATE TABLE `profiles` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `surname` varchar(255) NOT NULL,
  `reg_date` varchar(255) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `name` (`name`),
  KEY `surname` (`surname`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


в таблице помимо id может быть любое количество разных полей с индексами.
В таблице существует запись:
Код: sql
1.
2.
3.
4.
_____________________________________________
id   |    name    |  surname   |   regdate
_____________________________________________
1   |  Владимир   |   Иванов   |  01.01.2014


выплняю запросы:
Код: sql
1.
2.
INSERT INTO `profiles`(`name`, `surname`) VALUES ('Владимир', 'Иванов');
INSERT INTO `profiles`(`name`, `surname`) VALUES ('Иван', 'Владимирович');


После каждого запроса мне нужно вывести id записи.
При наличии похожих данных (запрос 1) вывести id существущей записи.
При отсутствии подобных данных в таблице (запрос 2), записать данные и вывести что-то вроде last_insert_id().

Это все делается удачно в вышеописанном коде, но делается жутко долго.

Если использовать ON DUPLICATE KEY UPDATE, то нужно чтобы id был уникальным полем и обязательно передавался в запросе.
Поэтому запрос:
Код: sql
1.
INSERT INTO `profiles`(`name`, `surname`) VALUES ('Владимир', 'Иванов') ON DUPLICATE KEY UPDATE `name`='Владимир', `surname`='Иванов';


не срабатывает, как хотелось бы, а просто записывает еще одну запись в таблицу.
Можно ли заставить при insert делать проверку на дубликаты по передаваемым полям, а не по уникальному ключу?
...
Рейтинг: 0 / 0
19.09.2014, 16:19:44
    #38751749
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
Артем_sqlМожно ли заставить при insert делать проверку на дубликаты по передаваемым полям, а не по уникальному ключу?Что мешает создать еще один уникальный ключ?
...
Рейтинг: 0 / 0
19.09.2014, 16:28:01
    #38751759
Артем_sql
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
miksoftАртем_sqlМожно ли заставить при insert делать проверку на дубликаты по передаваемым полям, а не по уникальному ключу?Что мешает создать еще один уникальный ключ?

какой например? name не могу, так как владимиров может быть много, как и surname.
для ясности скажу, что путем парсинга xml данных я записываю их в базу. в разных xml могут быть сведения об одном и том же человеке. в таком случае мне нужно избежать запись, а просто вывести id существующей записи.
...
Рейтинг: 0 / 0
19.09.2014, 16:35:16
    #38751768
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
Артем_sqlкакой например?(`name`, `surname`)
...
Рейтинг: 0 / 0
19.09.2014, 16:37:01
    #38751771
Артем_sql
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
Артем_sql name не могу, так как владимиров может быть много, как и surname.
...
Рейтинг: 0 / 0
19.09.2014, 16:37:31
    #38751773
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
Артем_sql,

Не понял, что Вы хотите сказать.
...
Рейтинг: 0 / 0
19.09.2014, 16:44:18
    #38751784
Артем_sql
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
miksoftАртем_sql,

Не понял, что Вы хотите сказать.

я хочу сказать, что ни одно поле сделать уникальным я не могу. Так как имена могут повторяться, как и фамилии.
...
Рейтинг: 0 / 0
19.09.2014, 16:46:33
    #38751789
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
Артем_sql,

Так я предлагаю не "одно поле", а уникальный ключ из двух полей. Даже круглые скобки оставил, чтобы удобно было в синтаксис копипастить.
...
Рейтинг: 0 / 0
19.09.2014, 16:55:47
    #38751805
Артем_sql
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
miksoftАртем_sql,

Так я предлагаю не "одно поле", а уникальный ключ из двух полей. Даже круглые скобки оставил, чтобы удобно было в синтаксис копипастить.
То есть как-то так ?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
CREATE TABLE `fixtures` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `ut` varchar(50) NOT NULL,
  `sport` varchar(50) NOT NULL,
  `country` varchar(25) DEFAULT NULL,
  `league` varchar(50) DEFAULT NULL,
  `template` varchar(255) DEFAULT NULL,
  `tournament` varchar(50) DEFAULT NULL,
  `status` varchar(25) NOT NULL DEFAULT 'Not started',
  PRIMARY KEY (`id`),
  UNIQUE KEY `sport_country_league` (`sport`,`country`,`league`),
  KEY `league` (`league`),
  KEY `country` (`country`),
  KEY `tournament` (`tournament`),
  KEY `sport` (`sport`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8
...
Рейтинг: 0 / 0
19.09.2014, 17:05:57
    #38751833
Артем_sql
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
Значит запрос делаю такой:
Код: sql
1.
INSERT ignore INTO `fixtures` ( `ut`, `sport`, `country`, `template`, `tournament`, `league`, `status`) VALUES ('2014-09-19','Football2','International1','International Friendlies','2014','International Friendlies','Not started')



А можно ли как-то максимально быстым образом вывести id после добавления в базу или вывести id существующей записи, если она есть?
...
Рейтинг: 0 / 0
19.09.2014, 17:09:39
    #38751842
Артем_sql
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
Артем_sqlА можно ли как-то максимально быстым образом вывести id после добавления в базу или вывести id существующей записи, если она есть?
просто, если это реализовать на php, то получается такой процесс:
1. делаю insert
2. при положительном результате делаю select last_insert_id()
3. при отрицательном результате делаю select id from...where {поля которые пытался записать}
И если записей несколько десятков тысяч, то система виснет
...
Рейтинг: 0 / 0
19.09.2014, 17:20:01
    #38751857
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
Делай 1) Insert Ignore 2) Select. Этого достаточно.
...
Рейтинг: 0 / 0
19.09.2014, 17:25:09
    #38751863
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
Артем_sqllast_insert_id()last_insert_id() полезен и в случае INSERT ... ON DUPLICATE KEY UPDATE.
См. LAST_INSERT_ID() , в т.ч. последний пример.
...
Рейтинг: 0 / 0
19.09.2014, 17:25:56
    #38751864
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
Артем_sqlИ если записей несколько десятков тысяч, то система виснетА это, скорее всего, потому что индексов не хватает. Создание ключа и этот момент облегчит.
...
Рейтинг: 0 / 0
19.09.2014, 21:02:58
    #38752072
Lumix
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
Артем_sqlАртем_sqlА можно ли как-то максимально быстым образом вывести id после добавления в базу или вывести id существующей записи, если она есть?
просто, если это реализовать на php, то получается такой процесс:
1. делаю insert
2. при положительном результате делаю select last_insert_id()
3. при отрицательном результате делаю select id from...where {поля которые пытался записать}
И если записей несколько десятков тысяч, то система виснет

Артем, такая задача решается так: в браузере на яваскрипте запускается очередь по модели связного списка на коллбеках и прогоняется весь список, таким образом каждое обращение к бекенду становится относительно дешевым и хотя у нас увеличивается время всей обработке и мы создаем чуть большую нагрузку на трафик, но сервер при этом мы не выжигаем, а система обретает огромную стабильность. Это решение проверено в очень серьезных проектах и не с десятками тысяч, а с дестяками миллионов записей!
...
Рейтинг: 0 / 0
20.09.2014, 00:35:16
    #38752205
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
miksoftАртем_sqlМожно ли заставить при insert делать проверку на дубликаты по передаваемым полям, а не по уникальному ключу?Что мешает создать еще один уникальный ключ?

Очевидно, отсутствие естественного ключа ...
...
Рейтинг: 0 / 0
20.09.2014, 00:37:42
    #38752206
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
Артем_sqlАртем_sqlА можно ли как-то максимально быстым образом вывести id после добавления в базу или вывести id существующей записи, если она есть?
просто, если это реализовать на php, то получается такой процесс:
1. делаю insert
2. при положительном результате делаю select last_insert_id()
3. при отрицательном результате делаю select id from...where {поля которые пытался записать}
И если записей несколько десятков тысяч, то система виснет

Лучше это делать на сервере, одним запросом, в хранимой процедуре.
...
Рейтинг: 0 / 0
20.09.2014, 14:14:57
    #38752382
Артем_sql
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
MasterZivЛучше это делать на сервере, одним запросом, в хранимой процедуре.

Не понимаю, почему запрос
Код: sql
1.
SELECT `id` FROM `fixtures` WHERE `sport` = 'Football' LIMIT 1


выводит id существующей записи, а если я делаю так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
CREATE DEFINER = 'root'@'localhost' FUNCTION `getid`(
        sport_name CHAR
    )
    RETURNS bigint(20)
    NOT DETERMINISTIC
    CONTAINS SQL
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN
  /* пробую так */
  RETURN (select id from `fixtures` where `sport`=CONCAT("'",sport_name,"'"));

  /* или так */
 RETURN (select id from `fixtures` where `sport`=sport_name);
END;

SELECT getid('Football');



в обоих случая ответ null.
Почему так? что я не так делаю? подскажите плиз..
...
Рейтинг: 0 / 0
20.09.2014, 14:18:46
    #38752385
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
Артем_sql,

А где Вы взяли конструкцию RETURN (SELECT ...) ?
...
Рейтинг: 0 / 0
20.09.2014, 14:22:03
    #38752389
Артем_sql
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
miksoftАртем_sql,

А где Вы взяли конструкцию RETURN (SELECT ...) ?

В инете копался, искал всякие примеры по созданию функций.
Изначально мой код был такой:
[code]
BEGIN
SET isset_id = (select id from `fixtures` where `sport`=sport_name);

IF isset_id is not null THEN
RETURN isset_id;
ELSE
INSERT INTO `fixtures` ( `sport`) VALUES ,sport);
SET insert_id = (select last_insert_id() as id);
RETURN insert_id;
END IF;
END;
[code]
...
Рейтинг: 0 / 0
20.09.2014, 14:31:28
    #38752393
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
Артем_sql,

Возможно, тот код был для других СУБД.
Освойте конструкцию SELECT ... INTO ...
См. http://dev.mysql.com/doc/refman/5.5/en/select-into.html
...
Рейтинг: 0 / 0
20.09.2014, 16:05:57
    #38752433
Артем_sql
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
ничего не понимаю...
В таблице имеются записи:
Код: sql
1.
2.
3.
id        sport 
1	Football
20	Box



Код процедуры:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
CREATE DEFINER = 'root'@'localhost' PROCEDURE `fixture_id`(
        IN id TINYINT(2)
    )
    NOT DETERMINISTIC
    CONTAINS SQL
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN
	DECLARE sport_name  VARCHAR(20);

	SELECT sport INTO sport_name FROM `fixtures` WHERE `id`= id LIMIT 1; 
	SELECT sport_name;
END;



Делаю запросы:
Код: sql
1.
2.
SELECT sport  FROM `fixtures` WHERE `id`= 1 LIMIT 1; /* ответ Football */
call fixture_id(1);  /* ответ Box  */



Как так? Что не так в коде?
...
Рейтинг: 0 / 0
20.09.2014, 16:08:22
    #38752437
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
Артем_sql
Код: sql
1.
`id`= id

id всегда равно id, чтобы это ни было :)

Называйте объекты в БД разными именами. Хотя бы в пределах одной области видимости.
...
Рейтинг: 0 / 0
20.09.2014, 16:14:05
    #38752442
Артем_sql
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
miksoftАртем_sql
Код: sql
1.
`id`= id

id всегда равно id, чтобы это ни было :)

Называйте объекты в БД разными именами. Хотя бы в пределах одной области видимости.

а разве id и `id` - это не разные вещи? никогда не обращал внимание на это :D
...
Рейтинг: 0 / 0
20.09.2014, 16:19:34
    #38752448
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите выбрать самый быстрый вариант
Артем_sqlа разве id и `id` - это не разные вещи?Нет, это одно и то же. Апострофы не обязательны для употребления, если идентификатор может быть корректно выделен в тексте запроса. Например, идентификаторы, которые совпадают с ключевыми словами, обязательно заключать в апострофы.
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / помогите выбрать самый быстрый вариант / 25 сообщений из 35, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]