user21 and Teake Nutma already posted the two methods I use most often. Of these I recommend Part as I believe it will be faster in general. Nevertheless these are hardly the only ways to accomplish this task. First, since the expression produced by List @@@ data will not be packed Thread may be faster than Transpose:
Thread[List @@@ data]
One could also thread over Rule, then replace the outer head with List:
List @@ Thread[data, Rule]
From Undocumented form for Extract we could also use:
Rest @ Extract[data, {{0}, {All, 1}, {All, 2}}]
Benchmarks
A BenchmarkPlot for all methods posted so far.
f1[a_] := a[[All, #]] & /@ {1, 2};
f2 = Transpose[# /. (a_ -> b_) :> {a, b}] &;
f3 = Transpose[List @@@ #] &;
f4 = Thread[List @@@ #] &;
f5 = List @@ Thread[#, Rule] &;
f6 = Rest@Extract[#, {{0}, {All, 1}, {All, 2}}] &;
f7 = Query[{Keys, Values}];
f8 = {Keys@#, Values@#} &
Needs["GeneralUtilities`"]
g[n_] := Rule @@@ RandomInteger[9, {n, 2}];
BenchmarkPlot[{f1, f2, f3, f4, f5, f6, f7, f8}, g, 2^Range[5, 20], "IncludeFits" -> True]
(click for larger)
Once again Query has some crazy overhead and should be avoided when performance matters unless inputs are very large.
Keys and Values are very fast when used apart from Query.
List @@ Thread[data, Rule] is as fast as Keys and Values, and faster than Part and Extract which I did not expect.
As expected Thread is slightly faster than Transpose with unpacked data. (f3 and f4)
{list1, list2} = {data[[All, 1]], data[[All, 2]]}– Mike Honeychurch Aug 07 '14 at 00:06