Можно ли как-то ускорить select из БД

Zaval

Новичок
Можно ли как-то ускорить select из БД

А проблема вот в чем:
есть 2 таблицы,
одна с id && name товара
другая купля продажа и тд. (tovar_go)
Вот ее структура:

date_in | in_ | c_in | date_go | go | date_out | out | c_out | bad | id_t

in_, go, out это поля типа enum '1','NULL'
- работают как метка закупка, выдача, продажа
с date_* думаю все ясно.

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

Если стержней (красных) :) пришло 10000 шт. то соответственно в базу
попадает такое же кол-во строк.

Вопрос 1 Совсем ли это криво?
Вопрос 2 Какую структуру (по правилам) должны иметь таблицы подобного типа?
Вопрос 3 Где почитать?
Вопрос 4 Мой запрос "ушустрить" можно? - кто че посоветует.

PHP:
 $res1 = mysql_query("SELECT id, name FROM tovar
  	WHERE fid = '".$CFirmaID."'
   	ORDER BY name"); echo mysql_error();
  while($row1=mysql_fetch_array($res1))
	{
		$resIN = mysql_query("SELECT 
		COUNT(go) AS kol, 
		AVG(c_in) AS cena 
		FROM tovar_go
  	WHERE id_t = '".$row1['id']."'"); echo mysql_error();
  	$rowIN = mysql_fetch_array($resIN);
  	
  	// То-же
  	$resGO = ...
  	$resOUT= ...
	}
В общем 3 вложенных запроса.
 

Demiurg

Guest
1. неправильно!!
3. что почитать ?
4. индексы.
 

tony2001

TeaM PHPClub
и про джойны почитай.
селекты в цикле вместо ЛЕФТ ДЖОЙНа - это смахивает на извращение.
 

Romantik

TeaM PHPClub
Если стержней (красных) пришло 10000 шт. то соответственно в базу
попадает такое же кол-во строк.
А зачем сделано так?
не проще ли таблицу с ID товара, ценой и кол-вом?
 

Zaval

Новичок
А зачем сделано так?
не проще ли таблицу с ID товара, ценой и кол-вом?
Конечно проще, я ждал этого вопроса.
НО как потом вычислить какой товар продан?

Закупка:
1. 10 шт. х 1,2
2. 12 шт. х 1,1
и. тд

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

Demiurg

Guest
Zaval, разберись пожалуйста с основами БД.
 

Romantik

TeaM PHPClub
Я делал так:
В накладной приход есть еще одно поле, равное кол-ву данного товара(кол2).
Потом при просчете доходов я пользовался этим полем с самого начала и если найденный ID товара и кол2>0
то я высчитывал ЭТУ разницу от расходной накладной и потом UPDATE .... кол2=кол2- КолТовараРасход. В итоге пока кол2не будет равно 0, списание идет сверху- так ИХО принято во многих программах и так верно. продавать надо, что раньше закуплено. Сложность возникает если расход кол=5 а в первой накл приход кол2 уже равен 2. Ну я думаю ты идею понял и этот алгоритм не составит особого труда....
 

Demiurg

Guest
Zaval, ты когда деньги считаешь, тоже палочками их обозначаешь ? один рубль - одна палочка.
 

Zaval

Новичок
Romantik
Раньше я почти так и делал только без дополнительного поля, просто высчитывал, но код страшно и показывать.
Думал существует более продвинутое решение.
Поюзаю с доп. полем может так вернее будет.
 

Romantik

TeaM PHPClub
может и существует более элегантное решение, но я пока додумался до такого. :)
 

Demiurg

Guest
>Скажи как надо?
надо сначала понять, что ты делаешь и как работает инструмент с которым ты работаешь.
 

Zaval

Новичок
Я еще пытался кол-во - цена во временную таблицу на палочки дробить но тоже тормоза, да и алгоритм на грани понимания :)
 

Zaval

Новичок
надо сначала понять, что ты делаешь и как работает инструмент с которым ты работаешь
Да понять что доход = продажа - закупка, не каждому дано.

Закупка:
1. 10 шт. х 1,2
2. 12 шт. х 1,1
3. 15 шт. х 1,5
и. тд

Продажа:
1. 8 шт. х 1,8
2. 9 шт. х 1,85
3. 11 шт. х 2,00

Если не сталкивался - кажется просто, а ты возьми да посчитай. :)
И причем здесь основы БД ?
 

Romantik

TeaM PHPClub
>И причем здесь основы БД ?

Планирование и понимание- 95 процентов успеха.
Представь, что у тебя появился товар "нитки" в километрах, а продаешь в метрах. Сколько строк у тебя будет? :)
 

Zaval

Новичок
:)
Ниток не будет!
И решение это временное. (с палочками).
Но тоже, интересно, ведь можно создать паралельно такую же таблицу с реальными кол. и "паковать" туда если кол. купленного х 1.2 уже продано - только разбить на даты, но для ниток и песка это не решение.
 

Zaval

Новичок
Ладно Romantik спасибо, буду юзать 2е поле.
Другого тут не светит.
Млин неужели никто подобного не делал?
Это-же из разряда классики!
 

LEglantier

Guest
Автор оригинала: Zaval

Закупка:
1. 10 шт. х 1,2
2. 12 шт. х 1,1
3. 15 шт. х 1,5
и. тд

Продажа:
1. 8 шт. х 1,8
2. 9 шт. х 1,85
3. 11 шт. х 2,00
А так считать совсем политически не грамотно?

Общая себестоимость "портфеля" стержней
(10*1,2+12*1,1+15*1,5)/(10+12+15) = 1,29 за штуку

Общая выручка от продажи одного стержня
(8*1,8+9*1,85+11*2)/(8+9+11) = 1,89

Доход:
(1,89-1,29)*(8+9+11) = 16,8

А то в натуре, лайфо какое-то получается:)))
Тогда можно будет держать в таблице с наименованиями текущую себестоимость (средневзвешенную) и просто пересчитывать ее с поступлением каждой новой партии.
(Сколько есть * Ср себест + Поступившие * Цена закупки)/(Сколько есть + Поступившие)

Ну, а, если так совсем нельзя... Ну, там складской учет и т.д. и надо именно продавать оперделенный стержень из определенной партии, то тогда хотя бы храни их не поштучно, а попартейно, постепенно, по мере продажи уменьшая количество стержней в партии с id=... Все-таки не 10000 строк на партию по указанной цене, а одна.
 

Romantik

TeaM PHPClub
То же вариант...
Тогда можно будет держать в таблице с наименованиями текущую себестоимость (средневзвешенную) и просто пересчитывать ее с поступлением каждой новой партии.
При работе во времени, когда у тебя давно закуплено и продано и этого товара нет на остатках- расчитывать Ср. цену с учетом этого товара безсмыслено. А когда тебе нужно знать реальные деньги на реальный день (сегодня, вчера и т.д. или за период)
то твой метод не даст точных расчетов.
поясню на примере:
ПРИХОД
20-01-2003 Товар1 10шт по 10руб
30-01-2003 Товар1 10шт по 12 руб

по твоему Ср.Цена= 11 руб.

РАСХОД
25-01-2003 Товар1 10шт по 15руб.

если мне нужен период с 20-01 по 25-01, то
по твоему:
ДОХОД за период равен
(10шт*15руб)-(10шт*11руб)= 40 руб, хотя реально 50 руб.
 
Сверху