Yorumları: 1.571
Konuları: 88
Kayıt Tarihi: 09-08-2016
Rep Puanı: 13.829 Üstad
(08-02-2019, Saat: 23:02)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: Listview’in varlığının amacı nedir ? Direkt veritabanına atmada bir problem mi var ?
Ben de bunu çok merak ediyorum???
ListView yoğun işlemler için oldukça maliyetlidir. Kullanılmak zorundaysa bile umarım "virtual mode"da kullanılıyordur.
There's no place like 127.0.0.1
Yorumları: 1.664
Konuları: 20
Kayıt Tarihi: 05-08-2016
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 19.042 Üstad
09-02-2019, Saat: 00:05
(Son Düzenleme: 09-02-2019, Saat: 00:09, Düzenleyen: mrmarman.)
@ SimaWB @ Tuğrul HELVACI
Aslında ListView'i iki boyutlu dizi örneği verirken kullanarak yanıltan benim.
Saniyede 400 veri geliyor deyince bunu bir havuzda biriktirip, toplu insert into ile 60 saniyede 1 yollarsa ağ sorunu, kayıtların teyidi için bir threadlik zamanı olur demiştim.
Mesajım aynen şuydu
Alıntı:- Aslında çözüm basit, örneğin 100'lük paketler halinde veritabanına yazın. Nasıl mı ? Anladınız bence.
"INSERT INTO" SQL cümlesi ile aynı anda dilediğiniz kadar veri insert edebilirsiniz.
INSERT INTO TabloAdi ( Data1, Data2, Data3 vs.vs.vs. Data399, Data400 )
VALUES
( 12.27, 14.30, 24.11 vs vs vs 123.11, 345.22, 399.90 ),
( 10.20, 11.10, 22.22 vs vs vs 113.21, 305.12, 310.90 ),
( 11.20, 13.10, 20.22 vs vs vs 110.20, 310.11, 388.88 ),
Vs
Vs
Vs
örneğinde olduğu gibi.
Sizin yapmanız gereken işlem bu verileri diziler halinde hafızada yer etmek. Belli bir sayıya ulaşınca da tümünü veritabanına bir batında yollamak olmalıdır. Böylece veritabanı erişimi sizin akışınızı etkilemeyecektir.
Paket kayıt sayısı size kalmış. dilerseniz 60'lı paketler yapın dakikada bir kayıt yapın, dilerseniz 3600'lü paketler yapın 1 saatte bir kayıt yapın. Önemli olan MySQL için göndereceğiniz paketin ağ altındaki durumu, internet üzerinden mi, yerelden mi olduğuna siz karar vereceksiniz.
Mesela analoji oluşsun diye basit düşünelim; bir ListView var ( bugünlerde çok soruda karşıma çıkınca aklıma ilk bu geldi ) cihazdan veri geldikçe bu listview'e bir Item ekleyip 400 tane SubItem eklediniz. Her eklediğiniz ITEM için STATE olarak örneğin (0) değeri verdiniz.
Size iki boyutlu bir dizi oldu. Bu veri sürekli eleniyor. Müdahale yok.
Belli bir sayıya gelince de olabilir belirli bir süre de olabilir, 0'dan Items.Count-1'e kadar bir döngü kurup bunları bir TEXT STRING içine yukarıda bahsettiğim SQL formunda yerleştirdikçe her satıra işlem gördüğüne ilişkin yeni bir STATE verin. Mesela (0) iken işlem gören satır STATE değeri (1) olsun.
MySQL kaydı sonucu SUCCESS döndüğünde bu STATE (1) olanları sileceksiniz. Hafıza rahatlayacak yenisine yer açılacaktır.
Bu mesaj forumdaki karşılığı ile örtüşmeyince gelişme olana kadar gözlem modunda bekliyorum ben de
Saygılarımla
Muharrem ARMAN
Yorumları: 670
Konuları: 73
Kayıt Tarihi: 20-12-2018
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 1.544 Programcı
09-02-2019, Saat: 00:08
(Son Düzenleme: 09-02-2019, Saat: 00:19, Düzenleyen: shooterman.)
(08-02-2019, Saat: 23:02)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: Listview’in varlığının amacı nedir ? Direkt veritabanına atmada bir problem mi var ?
Sn. Tuğrul Hocam,
İlgili component örneklemesinde, listview üzerinde geliyor veriler. Ben de bu örneklemeden yola çıkarak, listviewdaki sürekli update olan anlık verileri en hızlı şekilde veritabanına kaydetmeye çalışıyorum. Almam gereken program resimdekidir. Burada 15 kadar satır var lakin, 400-450 satıra yakın kayıt olacak. Buradaki veriler, 1 saniyede bir değişiyor. Veri tabanına insert işlemi yapıyorum ancak, 400 veriyi kaydetmesi 5 saniye sürüyor. Aradaki 4 saniyede, 4 farklı verileri kayıt edemeden gidiyor.
(09-02-2019, Saat: 00:05)mrmarman Adlı Kullanıcıdan Alıntı: @SimaWB @Tuğrul HELVACI
Aslında ListView'i iki boyutlu dizi örneği verirken kullanarak yanıltan benim.
Saniyede 400 veri geliyor deyince bunu bir havuzda biriktirip, toplu insert into ile 60 saniyede 1 yollarsa ağ sorunu, kayıtların teyidi için bir threadlik zamanı olur demiştim.
Estağfurullah Sn. Muharrem Hocam, ne yanıltması? Esasen ben tam izah edemedim sorunumu size.
Yazılımcı, kahveyi koda çeviren bir organizmadır.
Yorumları: 656
Konuları: 69
Kayıt Tarihi: 24-01-2018
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 892 Acemi
(08-02-2019, Saat: 21:45)narkotik Adlı Kullanıcıdan Alıntı: Hocam bende merak ettim şöyle bir deneme yaptım kendim yazdığım küçük işlerde kullandığım bir queryim var, bununla iyi sonuçlar aldım 1 dakika falan çalıştırdım. Kendine göre iyileştirmeler yapıp bir test et istersen.
unit NrWebServiceQuery;
interface
uses VirtualTable,System.SysUtils,System.Classes,Data.DB;
type
TNrWebServiceQuery = class(TVirtualTable)
private
FSQLTableName: String;
FSQLPrimaryFields: String;
FSQLBatch: TStrings;
FBatch: Boolean;
procedure SetSQLTableName(const Value: String);
procedure SetSQLPrimaryFields(const Value: String);
procedure SetSQLBatch(const Value: TStrings);
procedure SetBatch(const Value: Boolean);
function GetFieldList:String;
function GetFieldListNotPrimaryFields:String;
function GetFieldValue(AField:TField):String;
function GetFound: Boolean;
{ private declarations }
protected
{ protected declarations }
public
constructor Create(AOwner: TComponent); override;
Destructor Destroy; override;
procedure DoBeforePost; override;
published
property SQLTableName: String read FSQLTableName write SetSQLTableName;
property SQLPrimaryFields: String read FSQLPrimaryFields write SetSQLPrimaryFields;
property Batch: Boolean read FBatch write SetBatch;
property SQLBatch : TStrings read FSQLBatch write SetSQLBatch;
property Found: Boolean read GetFound;
end;
implementation
{ TNrWebServiceQuery }
constructor TNrWebServiceQuery.Create(AOwner: TComponent);
begin
inherited;
SQLBatch := TStringList.Create;
end;
destructor TNrWebServiceQuery.Destroy;
begin
SQLBatch.Free;
inherited;
end;
procedure TNrWebServiceQuery.DoBeforePost;
Var BatchString : String;
TempValue : String;
PTempValue : String;
PrimaryList : TStringList;
Ind : Integer;
begin
inherited;
if Batch then
begin
if SQLTableName = '' then
begin
SQLBatch.Add('SQLTableName boş olamaz!');
Exit;
end
else if SQLPrimaryFields = '' then
begin
SQLBatch.Add('SQLPrimaryFields boş olamaz!');
Exit;
end;
try
if State in [dsEdit] then
begin
BatchString := Concat('UPDATE ',SQLTableName,' SET ');
PrimaryList := TStringList.Create;
try
PrimaryList.BeginUpdate;
PrimaryList.Text := StringReplace(SQLPrimaryFields,',',sLineBreak,[rfReplaceAll]);
PrimaryList.EndUpdate;
for Ind := 0 to Pred(FieldCount) do
begin
If PrimaryList.IndexOf(Fields[Ind].FieldName) <> -1 then
begin
if PTempValue = '' then
PTempValue := Concat(Fields[Ind].FieldName,'=')
else
PTempValue := PTempValue + Concat(' AND ',Fields[Ind].FieldName,'=');
PTempValue := Concat(PTempValue,GetFieldValue(Fields[Ind]));
Continue;
end;
TempValue := Concat(TempValue,Fields[Ind].FieldName,'=',GetFieldValue(Fields[Ind]),',');
end;
TempValue := Copy(TempValue,1,TempValue.Length-1);
BatchString := Concat(BatchString,TempValue,' WHERE ',PTempValue);
SQLBatch.BeginUpdate;
SQLBatch.Add(BatchString);
SQLBatch.EndUpdate;
finally
FreeAndNil(PrimaryList);
end;
end
else if State in [dsInsert] then
begin
BatchString := Concat('INSERT INTO ',SQLTableName,'(',GetFieldListNotPrimaryFields,')',' VALUES(');
PrimaryList := TStringList.Create;
try
PrimaryList.BeginUpdate;
PrimaryList.Text := StringReplace(SQLPrimaryFields,',',sLineBreak,[rfReplaceAll]);
PrimaryList.EndUpdate;
for Ind := 0 to Pred(FieldCount) do
begin
If PrimaryList.IndexOf(Fields[Ind].FieldName) <> -1 then Continue;
TempValue := Concat(TempValue,GetFieldValue(Fields[Ind]),',');
end;
TempValue := Copy(TempValue,1,TempValue.Length-1);
BatchString := Concat(BatchString,TempValue,')');
SQLBatch.BeginUpdate;
SQLBatch.Add(BatchString);
SQLBatch.EndUpdate;
finally
FreeAndNil(PrimaryList);
end;
end;
Except
on e:Exception do
begin
SQLBatch.Add(e.Message);
end;
end;
end;
end;
function TNrWebServiceQuery.GetFieldList: String;
Var Ind : Integer;
begin
for Ind := 0 to Pred(FieldCount) do
Result := Concat(Result,Fields[Ind].FieldName,',');
Result := Copy(Result,1,Result.Length-1);
end;
function TNrWebServiceQuery.GetFieldListNotPrimaryFields: String;
Var Ind : Integer;
PrimaryList : TStringList;
begin
PrimaryList := TStringList.Create;
PrimaryList.BeginUpdate;
PrimaryList.Text := StringReplace(SQLPrimaryFields,',',sLineBreak,[rfReplaceAll]);
PrimaryList.EndUpdate;
try
for Ind := 0 to Pred(FieldCount) do
begin
If PrimaryList.IndexOf(Fields[Ind].FieldName) <> -1 then Continue;
Result := Concat(Result,Fields[Ind].FieldName,',');
end;
Result := Copy(Result,1,Result.Length-1);
finally
FreeAndNil(PrimaryList);
end;
end;
function TNrWebServiceQuery.GetFieldValue(AField:TField): String;
begin
case AField.DataType of
ftString : Result := QuotedStr(AField.AsString);
ftInteger : Result := IntToStr(AField.AsInteger);
ftFloat : Result := StringReplace(FloatToStr(AField.AsFloat),FormatSettings.DecimalSeparator,'.',[rfReplaceAll]);
ftDate : Result := QuotedStr(FormatDateTime('yyyy-mm-dd',AField.AsDateTime));
ftDateTime : Result := QuotedStr(FormatDateTime('yyyy-mm-dd hh:nn:ss:',AField.AsDateTime));
ftBlob : Result := QuotedStr(AField.AsString);
end;
end;
function TNrWebServiceQuery.GetFound: Boolean;
begin
Result := Active and (RecordCount > 0);
end;
procedure TNrWebServiceQuery.SetBatch(const Value: Boolean);
begin
FBatch := Value;
end;
procedure TNrWebServiceQuery.SetSQLBatch(const Value: TStrings);
begin
FSQLBatch := Value;
end;
procedure TNrWebServiceQuery.SetSQLPrimaryFields(const Value: String);
begin
FSQLPrimaryFields := Value;
end;
procedure TNrWebServiceQuery.SetSQLTableName(const Value: String);
begin
FSQLTableName := Value;
end;
end.
procedure TFrmTest.FormCreate(Sender: TObject);
begin
xLocalQuery := TNrWebServiceQuery.Create(nil);
xLocalQuery.FieldDefs.Add('VALUE',ftFloat);
xLocalQuery.FieldDefs.Add('ID',ftInteger);
xLocalQuery.SQLTableName := 'TEST_TABLE';
xLocalQuery.SQLPrimaryFields := 'ID';
xLocalQuery.Batch := True;
xLocalQuery.Open;
DataSource1.DataSet := xLocalQuery;
end;
procedure TFrmTest.Timer1Timer(Sender: TObject);
Var Ind : Integer;
begin
xLocalQuery.DisableControls;
xLocalQuery.SQLBatch.Clear;
xLocalQuery.Clear;
for Ind := 1 to 400 do
begin
xLocalQuery.Insert;
xLocalQuery.FieldByName('VALUE').Value := Ind;
xLocalQuery.Post;
end;
Caption := xLocalQuery.RecordCount.ToString;
xLocalQuery.EnableControls;
if xLocalQuery.SQLBatch.Text <> '' then
begin
QryTest.SQL.Text := xLocalQuery.SQLBatch.Text;
QryTest.ExecSQL;
end;
end;
Örnek kod için çok teşekkür ederim.
Yorumları: 1.460
Konuları: 80
Kayıt Tarihi: 05-08-2016
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 11.868 Üstad
(09-02-2019, Saat: 00:08)wiseman Adlı Kullanıcıdan Alıntı: (08-02-2019, Saat: 23:02)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: Listview’in varlığının amacı nedir ? Direkt veritabanına atmada bir problem mi var ?
Sn. Tuğrul Hocam,
İlgili component örneklemesinde, listview üzerinde geliyor veriler. Ben de bu örneklemeden yola çıkarak, listviewdaki sürekli update olan anlık verileri en hızlı şekilde veritabanına kaydetmeye çalışıyorum. Almam gereken program resimdekidir. Burada 15 kadar satır var lakin, 400-450 satıra yakın kayıt olacak. Buradaki veriler, 1 saniyede bir değişiyor. Veri tabanına insert işlemi yapıyorum ancak, 400 veriyi kaydetmesi 5 saniye sürüyor. Aradaki 4 saniyede, 4 farklı verileri kayıt edemeden gidiyor.
(09-02-2019, Saat: 00:05)mrmarman Adlı Kullanıcıdan Alıntı: @SimaWB @Tuğrul HELVACI
Aslında ListView'i iki boyutlu dizi örneği verirken kullanarak yanıltan benim.
Saniyede 400 veri geliyor deyince bunu bir havuzda biriktirip, toplu insert into ile 60 saniyede 1 yollarsa ağ sorunu, kayıtların teyidi için bir threadlik zamanı olur demiştim.
Estağfurullah Sn. Muharrem Hocam, ne yanıltması? Esasen ben tam izah edemedim sorunumu size.
Asıl sorun bence:
Alıntı:Veri tabanına insert işlemi yapıyorum ancak, 400 veriyi kaydetmesi 5 saniye sürüyor
Çok uzun bir zaman, hemde çooook uzun.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
Yorumları: 231
Konuları: 12
Kayıt Tarihi: 06-07-2018
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 1.178 Programcı
Ben de çok uzun bulduğum için batch update önermiştim.
Veya toplu sql falan da denenebilir.
|