powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / помогите выбрать самый быстрый вариант
35 сообщений из 35, показаны все 2 страниц
помогите выбрать самый быстрый вариант
    #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
помогите выбрать самый быстрый вариант
    #38751749
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Артем_sqlМожно ли заставить при insert делать проверку на дубликаты по передаваемым полям, а не по уникальному ключу?Что мешает создать еще один уникальный ключ?
...
Рейтинг: 0 / 0
помогите выбрать самый быстрый вариант
    #38751759
Артем_sql
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoftАртем_sqlМожно ли заставить при insert делать проверку на дубликаты по передаваемым полям, а не по уникальному ключу?Что мешает создать еще один уникальный ключ?

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

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

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

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

Так я предлагаю не "одно поле", а уникальный ключ из двух полей. Даже круглые скобки оставил, чтобы удобно было в синтаксис копипастить.
...
Рейтинг: 0 / 0
помогите выбрать самый быстрый вариант
    #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
помогите выбрать самый быстрый вариант
    #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
помогите выбрать самый быстрый вариант
    #38751842
Артем_sql
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Артем_sqlА можно ли как-то максимально быстым образом вывести id после добавления в базу или вывести id существующей записи, если она есть?
просто, если это реализовать на php, то получается такой процесс:
1. делаю insert
2. при положительном результате делаю select last_insert_id()
3. при отрицательном результате делаю select id from...where {поля которые пытался записать}
И если записей несколько десятков тысяч, то система виснет
...
Рейтинг: 0 / 0
помогите выбрать самый быстрый вариант
    #38751857
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Делай 1) Insert Ignore 2) Select. Этого достаточно.
...
Рейтинг: 0 / 0
помогите выбрать самый быстрый вариант
    #38751863
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Артем_sqllast_insert_id()last_insert_id() полезен и в случае INSERT ... ON DUPLICATE KEY UPDATE.
См. LAST_INSERT_ID() , в т.ч. последний пример.
...
Рейтинг: 0 / 0
помогите выбрать самый быстрый вариант
    #38751864
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Артем_sqlИ если записей несколько десятков тысяч, то система виснетА это, скорее всего, потому что индексов не хватает. Создание ключа и этот момент облегчит.
...
Рейтинг: 0 / 0
помогите выбрать самый быстрый вариант
    #38752072
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Артем_sqlАртем_sqlА можно ли как-то максимально быстым образом вывести id после добавления в базу или вывести id существующей записи, если она есть?
просто, если это реализовать на php, то получается такой процесс:
1. делаю insert
2. при положительном результате делаю select last_insert_id()
3. при отрицательном результате делаю select id from...where {поля которые пытался записать}
И если записей несколько десятков тысяч, то система виснет

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

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

Лучше это делать на сервере, одним запросом, в хранимой процедуре.
...
Рейтинг: 0 / 0
помогите выбрать самый быстрый вариант
    #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
помогите выбрать самый быстрый вариант
    #38752385
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Артем_sql,

А где Вы взяли конструкцию RETURN (SELECT ...) ?
...
Рейтинг: 0 / 0
помогите выбрать самый быстрый вариант
    #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
помогите выбрать самый быстрый вариант
    #38752393
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Артем_sql,

Возможно, тот код был для других СУБД.
Освойте конструкцию SELECT ... INTO ...
См. http://dev.mysql.com/doc/refman/5.5/en/select-into.html
...
Рейтинг: 0 / 0
помогите выбрать самый быстрый вариант
    #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
помогите выбрать самый быстрый вариант
    #38752437
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Артем_sql
Код: sql
1.
`id`= id

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

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

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

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

а разве id и `id` - это не разные вещи? никогда не обращал внимание на это :D
...
Рейтинг: 0 / 0
помогите выбрать самый быстрый вариант
    #38752448
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Артем_sqlа разве id и `id` - это не разные вещи?Нет, это одно и то же. Апострофы не обязательны для употребления, если идентификатор может быть корректно выделен в тексте запроса. Например, идентификаторы, которые совпадают с ключевыми словами, обязательно заключать в апострофы.
...
Рейтинг: 0 / 0
помогите выбрать самый быстрый вариант
    #38752552
Артем_sql
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В итоге получилось такое чудо:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
CREATE DEFINER = 'root'@'localhost' PROCEDURE `fixture_id`(
        _ut VARCHAR(50),
        _sport VARCHAR(50),
        _country VARCHAR(50),
        _template VARCHAR(50),
        _league  VARCHAR(50)
    )
    NOT DETERMINISTIC
    CONTAINS SQL
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN
	DECLARE inserted INT DEFAULT 0;
	DECLARE isset_id INT DEFAULT 0;
	
	SELECT id INTO isset_id FROM `fixtures` WHERE 
	`ut`= _ut and 
	`sport`= _sport and 
	`country`= _country and 
	`template`= _template and 
	`league`= _league 
	LIMIT 1;
	
	IF isset_id > 0 THEN
		SELECT isset_id 'id';
	ELSE
		INSERT INTO `fixtures` ( `ut`, `sport`, `country`, `template`, `tournament`, `league`, `status`) VALUES (_ut,_sport,_country,_template,'2014',_league,'Not started');
		SELECT LAST_INSERT_ID() INTO inserted;
		SELECT inserted 'id';
	END IF;
END;



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

Можно ли как-то оптимизировать код процедуры или запросы, чтобы быстрее работало?
...
Рейтинг: 0 / 0
помогите выбрать самый быстрый вариант
    #38752583
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
если судить по
Код: sql
1.
2.
SELECT LAST_INSERT_ID() INTO inserted;
		SELECT inserted 'id';


то нет ничего удивительного в долгом выполнении....
...
Рейтинг: 0 / 0
помогите выбрать самый быстрый вариант
    #38752592
Артем_sql
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
вадяесли судить по
Код: sql
1.
2.
SELECT LAST_INSERT_ID() INTO inserted;
		SELECT inserted 'id';


то нет ничего удивительного в долгом выполнении....

а на что заменить? посоветуй плиз
...
Рейтинг: 0 / 0
помогите выбрать самый быстрый вариант
    #38752606
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Артем_sql,

Сдается мне, что вообще всю эту процедуру можно заменить на один SQL-запрос вида INSERT ... ON DUPLICATE KEY UPDATE (См. комменты про LAST_INSERT_ID().)
...
Рейтинг: 0 / 0
помогите выбрать самый быстрый вариант
    #38752733
Артем_sql
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoftАртем_sql,

Сдается мне, что вообще всю эту процедуру можно заменить на один SQL-запрос вида INSERT ... ON DUPLICATE KEY UPDATE (См. комменты про LAST_INSERT_ID().)

все началось именно с on duplicate key :D но в процессе я запутался и ушел в глубь.

Во всяком случае по времени выполнения первых 5 запросов видно, что процедуры работают быстрее:


Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
INSERT INTO `fixtures` (`ut`,`sport`,`country`,`template`,`league`,`tournament`,`status`) VALUES ('2014-09-20','Football','International','Euro 2016','Euro 2016','2014','Not started') ON DUPLICATE KEY UPDATE ID = LAST_INSERT_ID(ID);
INSERT INTO `fixture_events` (`name`,`date`,`fixture_id`,`participants`,`visible`) VALUES ('Azerbaijan - Bulgaria','2014-09-09 15:00:00','1','a:2:{i:0;s:10:"Azerbaijan";i:1;s:8:"Bulgaria";}','1') ON DUPLICATE KEY UPDATE ID = LAST_INSERT_ID(ID);
INSERT INTO `odds_groups` (`sport`,`caption`) VALUES ('Football','Win') ON DUPLICATE KEY UPDATE ID = LAST_INSERT_ID(ID);
INSERT INTO `odds_types` (`group_id`,`caption`,`enabled`) VALUES ('1','%par1','1') ON DUPLICATE KEY UPDATE ID = LAST_INSERT_ID(ID);
INSERT INTO `odds` (`partner_id`,`event_id`,`date`,`odds`,`type_id`,`enabled`,`margin`) VALUES ('1','1','2014-09-20 19:37:03','4.1','1','1','1.8') ON DUPLICATE KEY UPDATE ID = LAST_INSERT_ID(ID);
в среднем - от 00.00.250 до  00.00.400 !

CALL fixture_id('2014-09-20','Football','International','Euro 2016','Euro 2016');
CALL event_id('Azerbaijan - Bulgaria','2014-09-09 15:00:00','1','a:2:{i:0;s:10:\"Azerbaijan\";i:1;s:8:\"Bulgaria\";}');
CALL group_id('Football','Win');
CALL type_id('1','%par1');
CALL save_odds('1','1','2014-09-20 19:36:48','4.1','1','1.8');
в среднем - от 00.00.650 до  00.01.250 !
...
Рейтинг: 0 / 0
помогите выбрать самый быстрый вариант
    #38752736
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Артем_sqlВо всяком случае по времени выполнения первых 5 запросов видно, что процедуры работают быстрее:Если цифры - это время, то медленнее, насколько я вижу.
...
Рейтинг: 0 / 0
помогите выбрать самый быстрый вариант
    #38752834
Артем_sql
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoftАртем_sqlВо всяком случае по времени выполнения первых 5 запросов видно, что процедуры работают быстрее:Если цифры - это время, то медленнее, насколько я вижу.

ой, я местами перепутал..:D
...
Рейтинг: 0 / 0
помогите выбрать самый быстрый вариант
    #38752840
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Артем_sqlвадяесли судить по
Код: sql
1.
2.
SELECT LAST_INSERT_ID() INTO inserted;
		SELECT inserted 'id';


то нет ничего удивительного в долгом выполнении....

а на что заменить? посоветуй плиз

Код: sql
1.
SELECT LAST_INSERT_ID() as `id`;



и есть подозрение, что ТС надо озвучить полную задачу, а не кусочки её решения, тогда может и будет предложено быстрое, правильное решение.
а так, по выше описанному, видно, что ТС не вполне владеет темой.
...
Рейтинг: 0 / 0
помогите выбрать самый быстрый вариант
    #38753477
Артем_sql
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
вадяАртем_sqlпропущено...


а на что заменить? посоветуй плиз

Код: sql
1.
SELECT LAST_INSERT_ID() as `id`;



и есть подозрение, что ТС надо озвучить полную задачу, а не кусочки её решения, тогда может и будет предложено быстрое, правильное решение.
а так, по выше описанному, видно, что ТС не вполне владеет темой.

как расшифровывается ТС?
...
Рейтинг: 0 / 0
помогите выбрать самый быстрый вариант
    #38753478
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Артем_sqlкак расшифровывается ТС?Топикстартер. Т.е. человек, который начал топик, написал самый первый пост.
...
Рейтинг: 0 / 0
35 сообщений из 35, показаны все 2 страниц
Форумы / MySQL [игнор отключен] [закрыт для гостей] / помогите выбрать самый быстрый вариант
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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