1 Востаннє редагувалося Betterthanyou (11.07.2020 15:01:18)

Тема: Оптимізація запита, дві вибірки в одній таблиці...

Є дві таблиці

`_Users` 
  `_id` INT NOT NULL AUTO_INCREMENT,
  `_UserId` INT UNSIGNED NULL,
  `_Username` VARCHAR(255) NULL DEFAULT null,
`_UsersDays` (
  `_id` INT NOT NULL AUTO_INCREMENT,
  `_KeyToUsers` INT NULL,
  `_CurrentDay` INT NULL,
  `_DateOfLastUpdate` INT NULL

Потрібно до поточного дня _CurrentDay додати один (+1) і записати точний час ( функція time в php )

UPDATE _UsersDays
SET _CurrentDay=
(
SELECT _CurrentDay
FROM _Users
WHERE _UserId=:_UserId
) + 1,
_DateOfLastUpdate=:_DateOfLastUpdate
WHERE _KeyToUsers=
(
SELECT _id
FROM _Users
WHERE _UserId=:_UserId2
);

Я два рази звертаюся до таблиці _Users, хоча все що мені від неї потрібно це _id, _CurrentDay поля які можна витягнути за один запит, але я не розумію як їх далі "розкидати" по потрібних місцях.

Як оптимізувати запит ?

2

Re: Оптимізація запита, дві вибірки в одній таблиці...

SELECT _CurrentDay
FROM _Users
WHERE _UserId=:_UserId

Це як? У _Users немає поля _CurrentDay.

Подякували: Betterthanyou1

3

Re: Оптимізація запита, дві вибірки в одній таблиці...

Якщо вам потрібно робити лише апдейт даних по ID користувача, (а він є в обох таблицях, вірно?) То навіщо смикати дані з обох?
І ще, моржна ж без вибірки плюсувати дані ( `_CurrentDay` + 1 )

Подякували: koala, Betterthanyou, leofun013

4

Re: Оптимізація запита, дві вибірки в одній таблиці...

UPDATE _UsersDays
SET _CurrentDay= _CurrentDay+ 1, _DateOfLastUpdate=NOW()
WHERE _UserId=:_UserId

Не воно?

Подякували: Betterthanyou1

5

Re: Оптимізація запита, дві вибірки в одній таблиці...

koala написав:
UPDATE _UsersDays
SET _CurrentDay= _CurrentDay+ 1, _DateOfLastUpdate=NOW()
WHERE _UserId=:_UserId

Не воно?

Замість NOW() хіба що UNIX_TIMESTAMP()

Подякували: koala, Betterthanyou2

6

Re: Оптимізація запита, дві вибірки в одній таблиці...

Дякую за допомогу

7

Re: Оптимізація запита, дві вибірки в одній таблиці...

koala написав:
SELECT _CurrentDay
FROM _Users
WHERE _UserId=:_UserId

Це як? У _Users немає поля _CurrentDay.

Не по темі
цього я пояснити не можу, як видно з скіра запит виконався без помилки
https://i.ibb.co/fMfhRX0/1234.jpg

Хоча цей запит

UPDATE _UsersDays
SET _CurrentDay=
(
SELECT a._CurrentDay
FROM _UsersDays AS a
LEFT JOIN _Users AS b
ON a._KeyToUsers=b._id
WHERE b._UserId=669168176
) + 1,
_DateOfLastUpdate=0
WHERE _KeyToUsers=
(
SELECT d._id
FROM _UsersDays AS c
LEFT JOIN _Users AS d
ON c._KeyToUsers=d._id
WHERE d._UserId=669168176
)

з помилкою Error Code: 1093. You can't specify target table '_UsersDays' for update in FROM clause

Вже не актуально, тому що koala допоміг оптимізувати запит, але цікаво чому так сталося...

8

Re: Оптимізація запита, дві вибірки в одній таблиці...

Тому що це був _CurrentDay з таблиці _UsersDays (яка в UPDATE). Перший запит був константним (тобто приблизно як "SELECT 1 FROM... WHERE..."). Він ніяк не впливав на _CurrentDay.
Запити неідентичні - я з другим запитом не розібрався. Можете пояснити, чому в `_Users` два поля `_id` та `_UserId` і в чому різниця?

9 Востаннє редагувалося Betterthanyou (11.07.2020 16:48:27)

Re: Оптимізація запита, дві вибірки в одній таблиці...

koala написав:

Запити неідентичні - я з другим запитом не розібрався. Можете пояснити, чому в `_Users` два поля `_id` та `_UserId` і в чому різниця?

_id - це первинний ключ який є унікальним.
_UserId - це ід користувача яке надається стороннім сервісом, ключ _UserId має бути унікальним, але я не впевнений в цьому тому я зробив "своє" ід (тобто _id).

10

Re: Оптимізація запита, дві вибірки в одній таблиці...

Тоді, схоже, там ще потрібен JOIN

UPDATE _UsersDays INNER JOIN _Users ON _UsersDays._KeyToUsers = _Users._id
SET _CurrentDay= _CurrentDay+ 1, _DateOfLastUpdate=UNIX_TIMESTAMP()
WHERE _UserId=:_UserId
Подякували: Betterthanyou1

11

Re: Оптимізація запита, дві вибірки в одній таблиці...

koala написав:

Тоді, схоже, там ще потрібен JOIN

UPDATE _UsersDays INNER JOIN _Users ON _UsersDays._KeyToUsers = _Users._id
SET _CurrentDay= _CurrentDay+ 1, _DateOfLastUpdate=UNIX_TIMESTAMP()
WHERE _UserId=:_UserId

Так я це зрозумів і написав такий запит

UPDATE _UsersDays
SET _CurrentDay=_CurrentDay+1, _DateOfLastUpdate=UNIX_TIMESTAMP()
WHERE _KeyToUsers=
(SELECT _id FROM _Users WHERE _UserId=:_UserId);

Те що можна в update прописувати JOIN я не знав, дякую