Laden...

SQL Filestreaming schneller als erlaubt?

Erstellt von kampfsau vor 12 Jahren Letzter Beitrag vor 12 Jahren 1.598 Views
K
kampfsau Themenstarter:in
15 Beiträge seit 2009
vor 12 Jahren
SQL Filestreaming schneller als erlaubt?

Hallo,

ich schreibe Testweise 11x100MB in eine SQL-Server 2008R2 Datenbank. Hierfür nutze ich die .Net Klasse SqlFileStreaming. Vor dem Öffnen und nach dem Schließen der Verbindung nehme ich die Zeit, bilde die Differenz und bekomme 998ms !! Das würde ja bedeuten, dass ich mit ca 1100 MBps bzw 8800 Mbps also knapp 8,6 Gbps lesen würde. Da ich mit Sata 3.0 aber nur einen theoretischen Durchsatz von 3,0 Gbps habe kann hier doch irgendwas nicht stimmen oder?

Ich freu mich schon auf eure Antworten.. 😉

G
538 Beiträge seit 2008
vor 12 Jahren

Ich würde auf einen Systematischen Testfehler tippen ....

Der Vorteil der Klugheit liegt darin, dass man sich dumm stellen kann - umgekehrt ist das schon schwieriger (K. Tucholsky)
Das Problem mit Internet-Zitaten ist, dass sie oftmals zu unrecht als authentisch angenommen werden. (K. Adenauer)

K
kampfsau Themenstarter:in
15 Beiträge seit 2009
vor 12 Jahren
SqlCommand cmd = new SqlCommand();
            SqlFileStream sqlFS;
            SqlDataReader dr;
            
            con.Open();
            cmd.Connection = con;
            cmd.CommandText = "SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()";
            cmd.CommandType = CommandType.Text;
            cmd.Transaction = con.BeginTransaction();
            byte[] token = (byte[])cmd.ExecuteScalar();

            cmd.CommandText = "SELECT streamData.PathName() FROM tbFS WHERE Id = " + id[0];
            cmd.CommandType = CommandType.Text;

            starta = DateTime.Now;
            for (int i = 0; i <= passes; i++)
            {
                nodePass = doc.CreateElement("p" + i.ToString());
                start = DateTime.Now;

                dr = cmd.ExecuteReader();
                dr.Read();
                string tmp = dr[0].ToString();
                sqlFS = new SqlFileStream(tmp, token, FileAccess.Read);
                data = new byte[sqlFS.Length];
                sqlFS.Read(data, 0, Convert.ToInt32(sqlFS.Length));
                sqlFS.Close();
                dr.Close();

                end = DateTime.Now;
                TimeSpan ts = end - start;
                nodePass.InnerText = ts.TotalMilliseconds.ToString() + " ms";
                nodeTry.AppendChild(nodePass);
                
            }                        
            cmd.Transaction.Commit();
            con.Close();
            enda = DateTime.Now;
            TimeSpan tsa = enda - starta;
            MessageBox.Show("Größe: " + (data.Length / 1024 / 1024).ToString() + " MB = " + (data.Length / 1024 / 1024 * 8).ToString() + " Mb\r\n"
                            + "Geschwindigkeit: " + (data.Length / 1024 / 1024) / (tsa.TotalMilliseconds / 1000 / passes + 1) + " MBps = " + (data.Length / 1024 / 1024 * 8) / (tsa.TotalMilliseconds / 1000 / passes + 1) + " Mbps");
            nodePass = doc.CreateElement("g");
            nodePass.InnerText = tsa.TotalMilliseconds.ToString();
            nodeTry.AppendChild(nodePass);

das ist der code..

Hinweis von Abt vor 12 Jahren

Bitte den Code direkt im Forum posten, anstatt einen Drittanbieter zu verwenden.

G
538 Beiträge seit 2008
vor 12 Jahren

Ich könnte mir vorstellen, dass du Daten aus einem Chache ausliest, den der SQL Server füllt, ohne dass du das mitbekommst - d.h. es könnte sein, dass du die Daten gar nicht von der Festplatte lädtst - sondern aus dem RAM.

100MB in 1 Sek von der Festplatte wäre dennoch recht flott, wenn du nicht grade ne SSD hast.

Im übrigen liest du daten - schreiben ist nicht read ...

Der Vorteil der Klugheit liegt darin, dass man sich dumm stellen kann - umgekehrt ist das schon schwieriger (K. Tucholsky)
Das Problem mit Internet-Zitaten ist, dass sie oftmals zu unrecht als authentisch angenommen werden. (K. Adenauer)

K
kampfsau Themenstarter:in
15 Beiträge seit 2009
vor 12 Jahren

ja du hast recht.. ich lese.. 😉

hab den code jetz noch ein wenig verändert:

SqlCommand cmd = new SqlCommand();
            SqlCommand cmdH = new SqlCommand();
            SqlFileStream sqlFS;
            SqlDataReader dr;
            
            con.Open();
            cmd.Connection = con;
            cmdH.Connection = con;
            cmd.CommandText = "SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()";
            cmd.CommandType = CommandType.Text;
            cmd.Transaction = con.BeginTransaction();
            cmdH.Transaction = cmd.Transaction;
            byte[] token = (byte[])cmd.ExecuteScalar();
            cmd.CommandText = "SELECT streamData.PathName() FROM tbFS WHERE Id = " + id[0];
            cmd.CommandType = CommandType.Text;

            starta = DateTime.Now;
            for (int i = 0; i <= passes; i++)
            {
                nodePass = doc.CreateElement("p" + i.ToString());
                cmdH.CommandText = "DBCC DROPCLEANBUFFERS; DBCC FREEPROCCACHE; dbcc freesystemcache('all')";
                cmdH.CommandType = CommandType.Text;
                cmdH.ExecuteNonQuery();
                start = DateTime.Now;

                dr = cmd.ExecuteReader();
                dr.Read();
                string tmp = dr[0].ToString();
                sqlFS = new SqlFileStream(tmp, token, FileAccess.Read);
                data = new byte[sqlFS.Length];
                sqlFS.Read(data, 0, Convert.ToInt32(sqlFS.Length));
                sqlFS.Close();
                dr.Close();

                end = DateTime.Now;
                TimeSpan ts = end - start;
                nodePass.InnerText = ts.TotalMilliseconds.ToString() + " ms";
                nodeTry.AppendChild(nodePass);
                
            }                        
            cmd.Transaction.Commit();
            con.Close();
            enda = DateTime.Now;
            TimeSpan tsa = enda - starta;
            MessageBox.Show("Größe: " + (data.Length / 1024 / 1024).ToString() + " MB = " + (data.Length / 1024 / 1024 * 8).ToString() + " Mb\r\n"
                            + "Geschwindigkeit: " + (data.Length / 1024 / 1024) / (tsa.TotalMilliseconds / 1000 / passes + 1) + " MBps = " + (data.Length / 1024 / 1024 * 8) / (tsa.TotalMilliseconds / 1000 / passes + 1) + " Mbps");
            nodePass = doc.CreateElement("g");
            nodePass.InnerText = tsa.TotalMilliseconds.ToString();
            nodeTry.AppendChild(nodePass);

lösche nun vor jedem durchlauf den cache des sql-servers.. nun brauche ich etwa 1,5s für 1100 MB. Trotzdem recht flott..

verbaut sind 2 WD5000AADS im raid 1, 12 gb ram, supermicro x8ste, intel xenon E5520

G
538 Beiträge seit 2008
vor 12 Jahren

Nun hast du noch den Fall, dass Windows vielleicht irgendwo was in einem Cache ablegt.

Ich würde dir empfehlen VERSCHIEDENE Daten zu lesen - oder tatsächlich welche zu schreiben - dann kannst du zufallsdaten benutzen ..

Der Vorteil der Klugheit liegt darin, dass man sich dumm stellen kann - umgekehrt ist das schon schwieriger (K. Tucholsky)
Das Problem mit Internet-Zitaten ist, dass sie oftmals zu unrecht als authentisch angenommen werden. (K. Adenauer)

K
kampfsau Themenstarter:in
15 Beiträge seit 2009
vor 12 Jahren

das habe ich auch schon versucht.. bringt nix.. die geschwindigkeit ist immernoch viel zu fix..